Browse Source

Commiting files that were not commited on previous commit

olegkap_cp 12 years ago
parent
commit
6dc8840e45

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

@@ -17,7 +17,7 @@ namespace Renci.SshNet
     /// </summary>
     /// </summary>
     public partial class ScpClient
     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>
         /// <summary>
         /// Uploads the specified file or directory to the remote host.
         /// Uploads the specified file or directory to the remote host.
         /// </summary>
         /// </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 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;
         private uint C0, C1, C2, C3;
 
 
@@ -634,9 +606,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 throw new IndexOutOfRangeException("output buffer too short");
                 throw new IndexOutOfRangeException("output buffer too short");
             }
             }
 
 
+            if (this._encryptionKey == null)
+            {
+                this._encryptionKey = this.GenerateWorkingKey(true, this.Key);
+            }
+
             this.UnPackBlock(inputBuffer, inputOffset);
             this.UnPackBlock(inputBuffer, inputOffset);
 
 
-            this.EncryptBlock(this.EncryptionKey);
+            this.EncryptBlock(this._encryptionKey);
 
 
             this.PackBlock(outputBuffer, outputOffset);
             this.PackBlock(outputBuffer, outputOffset);
 
 
@@ -674,16 +651,21 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 throw new IndexOutOfRangeException("output buffer too short");
                 throw new IndexOutOfRangeException("output buffer too short");
             }
             }
 
 
+            if (this._decryptionKey == null)
+            {
+                this._decryptionKey = this.GenerateWorkingKey(false, this.Key);
+            }
+
             this.UnPackBlock(inputBuffer, inputOffset);
             this.UnPackBlock(inputBuffer, inputOffset);
 
 
-            this.DecryptBlock(this.DecryptionKey);
+            this.DecryptBlock(this._decryptionKey);
 
 
             this.PackBlock(outputBuffer, outputOffset);
             this.PackBlock(outputBuffer, outputOffset);
 
 
             return this.BlockSize;
             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
             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.");
                 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
             _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
             // 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++)
             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;
                 i += 4;
             }
             }
 
 
@@ -712,7 +694,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             int k = (_rounds + 1) << 2;
             int k = (_rounds + 1) << 2;
             for (int i = KC; (i < k); i++)
             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)
                 if ((i % KC) == 0)
                 {
                 {
                     temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC) - 1];
                     temp = SubWord(Shift(temp, 8)) ^ rcon[(i / KC) - 1];
@@ -722,7 +704,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                     temp = SubWord(temp);
                     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)
             if (!isEncryption)
@@ -731,7 +713,7 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
                 {
                 {
                     for (int i = 0; i < 4; i++)
                     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);
             UInt32ToLittleEndian(C3, bytes, off + 12);
         }
         }
 
 
-        private void EncryptBlock(uint[,] KW)
+        private void EncryptBlock(uint[] KW)
         {
         {
             int r;
             int r;
             uint r0, r1, r2, r3;
             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; )
             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
             // 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;
             int r;
             uint r0, r1, r2, r3;
             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; )
             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
             // 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>
     /// <summary>
     /// Implements ARCH4 cipher algorithm
     /// Implements ARCH4 cipher algorithm
     /// </summary>
     /// </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
         public override byte MinimumSize
         {
         {
             get { return 0; }
             get { return 0; }
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Initializes a new instance of the <see cref="Arc4Cipher"/> class.
+        /// Initializes a new instance of the <see cref="Arc4Cipher" /> class.
         /// </summary>
         /// </summary>
         /// <param name="key">The key.</param>
         /// <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)
         public Arc4Cipher(byte[] key, bool dischargeFirstBytes)
             : base(key)
             : base(key)
         {
         {
-            workingKey = key;
-            SetKey(workingKey);
+            this._workingKey = key;
+            SetKey(this._workingKey);
             //   The first 1536 bytes of keystream
             //   The first 1536 bytes of keystream
             //   generated by the cipher MUST be discarded, and the first byte of the
             //   generated by the cipher MUST be discarded, and the first byte of the
             //   first encrypted packet MUST be encrypted using the 1537th byte of
             //   first encrypted packet MUST be encrypted using the 1537th byte of
@@ -95,18 +115,6 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
             return output;
             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)
         private int ProcessBytes(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
         {
             if ((inputOffset + inputCount) > inputBuffer.Length)
             if ((inputOffset + inputCount) > inputBuffer.Length)
@@ -121,45 +129,41 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
 
             for (int i = 0; i < inputCount; i++)
             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
                 // 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
                 // 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;
             return inputCount;
         }
         }
 
 
-        public void Reset()
+        private void Reset()
         {
         {
-            SetKey(workingKey);
+            SetKey(this._workingKey);
         }
         }
 
 
-        // Private implementation
-
         private void SetKey(byte[] keyBytes)
         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
             // 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;
             int i1 = 0;
@@ -167,14 +171,13 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
 
             for (int i = 0; i < STATE_LENGTH; i++)
             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
                 // 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;
                 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>
 	/// <summary>
     /// Blowfish cipher implementation.
     /// Blowfish cipher implementation.
     /// </summary>
     /// </summary>
-	public class BlowfishCipher : BlockCipher
+	public sealed class BlowfishCipher : BlockCipher
 	{
 	{
 		#region Static reference tables
 		#region Static reference tables
 
 
@@ -297,9 +297,15 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
 
 		private static readonly int _pSize = _rounds + 2;
 		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>
 		/// <summary>
 		/// Initializes a new instance of the <see cref="BlowfishCipher"/> class.
 		/// Initializes a new instance of the <see cref="BlowfishCipher"/> class.
@@ -509,6 +515,5 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 				xl = table[s];
 				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>
     /// <summary>
     /// Implements CAST cipher algorithm
     /// Implements CAST cipher algorithm
     /// </summary>
     /// </summary>
-    public class CastCipher : BlockCipher
+    public sealed class CastCipher : BlockCipher
     {
     {
         internal static readonly int MAX_ROUNDS = 16;
         internal static readonly int MAX_ROUNDS = 16;
+
         internal static readonly int RED_ROUNDS = 12;
         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;
         private int _rounds = MAX_ROUNDS;
 
 
@@ -381,12 +389,10 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 
 
         #endregion
         #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)
         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);
             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)
         private static uint F1(uint D, uint Kmi, int Kri)
         {
         {
             uint I = Kmi + D;
             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];
             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)
         private static uint F2(uint D, uint Kmi, int Kri)
         {
         {
             uint I = Kmi ^ D;
             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];
             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)
         private static uint F3(uint D, uint Kmi, int Kri)
         {
         {
             uint I = Kmi - D;
             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];
             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)
         private void CastEncipher(uint L0, uint R0, uint[] result)
         {
         {
             uint Lp = L0;        // the previous value, equiv to L[i-1]
             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>
 	/// <summary>
 	/// Implements Serpent cipher algorithm.
 	/// Implements Serpent cipher algorithm.
 	/// </summary>
 	/// </summary>
-	public class SerpentCipher : BlockCipher
+	public sealed class SerpentCipher : BlockCipher
 	{
 	{
 		private static readonly int ROUNDS = 32;
 		private static readonly int ROUNDS = 32;
+
 		private static readonly int PHI = unchecked((int)0x9E3779B9);       // (Sqrt(5) - 1) * 2**31
 		private static readonly int PHI = unchecked((int)0x9E3779B9);       // (Sqrt(5) - 1) * 2**31
 
 
 		private int[] _workingKey;
 		private int[] _workingKey;
@@ -321,23 +322,23 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			return w;
 			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)));
 			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)));
 			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) |
 			return (((src[srcOff] & 0xff) << 24) | ((src[srcOff + 1] & 0xff) << 16) |
 			((src[srcOff + 2] & 0xff) << 8) | ((src[srcOff + 3] & 0xff)));
 			((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 + 3] = (byte)(word);
 			dst[dstOff + 2] = (byte)((uint)word >> 8);
 			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 */
 		/* We hereby give permission for information in this file to be */
 		/* used freely subject only to acknowledgement of its origin.    */
 		/* 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 t1 = a ^ d;
 			int t3 = c ^ t1;
 			int t3 = c ^ t1;
@@ -385,10 +390,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = t12 ^ (~t7);
 			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 t1 = ~a;
 			int t2 = a ^ b;
 			int t2 = a ^ b;
@@ -401,10 +410,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = this._x3 ^ (t5 ^ t8);
 			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 t2 = b ^ (~a);
 			int t5 = c ^ (a | t2);
 			int t5 = c ^ (a | t2);
@@ -417,10 +430,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = t5 ^ (t8 & t11);
 			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 t1 = b ^ d;
 			int t3 = a ^ (b & t1);
 			int t3 = a ^ (b & t1);
@@ -435,10 +452,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = t4 ^ (t10 | t11);
 			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 t1 = ~a;
 			int t2 = b ^ d;
 			int t2 = b ^ d;
@@ -452,10 +473,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x1 = (t2 ^ this._x3) ^ (this._x2 ^ (d | t1));
 			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 t1 = b ^ d;
 			int t2 = ~t1;
 			int t2 = ~t1;
@@ -473,10 +498,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (d & t11) ^ (t3 ^ t12);
 			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 t1 = a ^ b;
 			int t2 = a & c;
 			int t2 = a & c;
@@ -494,10 +523,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x3 = (b | d) ^ (t4 ^ t12);
 			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 t1 = a | b;
 			int t2 = b ^ c;
 			int t2 = b ^ c;
@@ -515,10 +548,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x1 = this._x3 ^ (this._x0 ^ t11);
 			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 t1 = a ^ d;
 			int t2 = d & t1;
 			int t2 = d & t1;
@@ -535,10 +572,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x1 = (a ^ t3) ^ (t10 & this._x2);
 			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 t1 = c | d;
 			int t2 = a & t1;
 			int t2 = a & t1;
@@ -555,10 +596,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (t3 & t11) ^ (this._x1 ^ t7);
 			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 t1 = ~a;
 			int t2 = a ^ b;
 			int t2 = a ^ b;
@@ -576,10 +621,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x3 = (b ^ t7) ^ (this._x1 & t12);
 			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 t1 = ~c;
 			int t2 = b & t1;
 			int t2 = b & t1;
@@ -596,10 +645,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (b & t10) ^ (t4 | (a ^ c));
 			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 t1 = ~a;
 			int t2 = a ^ d;
 			int t2 = a ^ d;
@@ -616,10 +669,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x3 = (~t5) ^ (t3 & t11);
 			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 t1 = ~a;
 			int t2 = a ^ b;
 			int t2 = a ^ b;
@@ -636,10 +693,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x2 = (d & t1) ^ (t3 ^ t11);
 			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 t1 = b ^ c;
 			int t2 = c & t1;
 			int t2 = c & t1;
@@ -657,10 +718,14 @@ namespace Renci.SshNet.Security.Cryptography.Ciphers
 			this._x0 = (~t11) ^ (this._x3 & this._x2);
 			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 t3 = c | (a & b);
 			int t4 = d & (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));
 			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()
 		private void LT()
 		{
 		{
 			int x0 = RotateLeft(this._x0, 13);
 			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);
 			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()
 		private void InverseLT()
 		{
 		{
 			int x2 = RotateRight(this._x2, 22) ^ this._x3 ^ (this._x1 << 7);
 			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>
     /// <summary>
     /// Implements 3DES cipher algorithm.
     /// Implements 3DES cipher algorithm.
     /// </summary>
     /// </summary>
-    public class TripleDesCipher : DesCipher
+    public sealed class TripleDesCipher : DesCipher
     {
     {
         private int[] _encryptionKey1;
         private int[] _encryptionKey1;
+
         private int[] _encryptionKey2;
         private int[] _encryptionKey2;
+
         private int[] _encryptionKey3;
         private int[] _encryptionKey3;
 
 
         private int[] _decryptionKey1;
         private int[] _decryptionKey1;
+
         private int[] _decryptionKey2;
         private int[] _decryptionKey2;
+
         private int[] _decryptionKey3;
         private int[] _decryptionKey3;
 
 
         /// <summary>
         /// <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
 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) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8,
 			(byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
 			(byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
 			(byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78,
 			(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) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0,
 			(byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
 			(byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
 			(byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42,
 			(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) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4,
 			(byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
 			(byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
 			(byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B,
 			(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) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4,
 			(byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
 			(byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
 			(byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56,
 			(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.
 		* Define the fixed p0/p1 permutations used in keyed S-box lookup.
 		* By changing the following constant definitions, the S-boxes will
 		* By changing the following constant definitions, the S-boxes will
 		* automatically Get changed in the Twofish engine.
 		* 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>
     /// <summary>
     /// MD5 algorithm implementation
     /// MD5 algorithm implementation
     /// </summary>
     /// </summary>
-    public class MD5Hash : HashAlgorithm
+    public sealed class MD5Hash : HashAlgorithm
     {
     {
         private byte[] _buffer = new byte[4];
         private byte[] _buffer = new byte[4];
         private int _bufferOffset;
         private int _bufferOffset;
@@ -170,9 +170,13 @@ namespace Renci.SshNet.Security.Cryptography
 
 
         private void InternalInitialize()
         private void InternalInitialize()
         {
         {
+            var i = 0;
             this._byteCount = 0;
             this._byteCount = 0;
             this._bufferOffset = 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);
             H1 = unchecked((int)0x67452301);
             H2 = unchecked((int)0xefcdab89);
             H2 = unchecked((int)0xefcdab89);
@@ -180,8 +184,7 @@ namespace Renci.SshNet.Security.Cryptography
             H4 = unchecked((int)0x10325476);
             H4 = unchecked((int)0x10325476);
 
 
             this._offset = 0;
             this._offset = 0;
-
-            for (int i = 0; i != this._hashValue.Length; i++)
+            for (i = 0; i != this._hashValue.Length; i++)
             {
             {
                 this._hashValue[i] = 0;
                 this._hashValue[i] = 0;
             }
             }
@@ -254,7 +257,7 @@ namespace Renci.SshNet.Security.Cryptography
         /*
         /*
         * rotate int x left n bits.
         * 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));
             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.
         * 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);
             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);
             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;
             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);
             return v ^ (u | ~w);
         }
         }
@@ -383,6 +386,5 @@ namespace Renci.SshNet.Security.Cryptography
                 this._hashValue[i] = 0;
                 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>
     /// 
     /// 
     /// </summary>
     /// </summary>
-    public class RIPEMD160Hash : HashAlgorithm
+    public sealed class RIPEMD160Hash : HashAlgorithm
     {
     {
         private const int DIGEST_SIZE = 20;
         private const int DIGEST_SIZE = 20;
 
 
@@ -85,7 +85,7 @@ namespace Renci.SshNet.Security.Cryptography
             //
             //
             // fill the current word
             // fill the current word
             //
             //
-            while ((_bufferOffset != 0) && (cbSize > 0))
+            while ((this._bufferOffset != 0) && (cbSize > 0))
             {
             {
                 this.Update(array[ibStart]);
                 this.Update(array[ibStart]);
                 ibStart++;
                 ibStart++;
@@ -95,13 +95,13 @@ namespace Renci.SshNet.Security.Cryptography
             //
             //
             // process whole words.
             // process whole words.
             //
             //
-            while (cbSize > _buffer.Length)
+            while (cbSize > this._buffer.Length)
             {
             {
                 this.ProcessWord(array, ibStart);
                 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()
         protected override byte[] HashFinal()
         {
         {
             var output = new byte[DIGEST_SIZE];
             var output = new byte[DIGEST_SIZE];
-            long bitLength = (_byteCount << 3);
+            long bitLength = (this._byteCount << 3);
 
 
             //
             //
             // add the pad bytes.
             // add the pad bytes.
@@ -142,11 +142,17 @@ namespace Renci.SshNet.Security.Cryptography
             return output;
             return output;
         }
         }
 
 
+        /// <summary>
+        /// Initializes an implementation of the <see cref="T:System.Security.Cryptography.HashAlgorithm" /> class.
+        /// </summary>
         public override void Initialize()
         public override void Initialize()
         {
         {
             this.InternalInitialize();
             this.InternalInitialize();
         }
         }
 
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RIPEMD160Hash" /> class.
+        /// </summary>
         public RIPEMD160Hash()
         public RIPEMD160Hash()
         {
         {
             this._buffer = new byte[4];
             this._buffer = new byte[4];
@@ -155,10 +161,10 @@ namespace Renci.SshNet.Security.Cryptography
 
 
         private void ProcessWord(byte[] input, int inOff)
         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);
                 | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24);
 
 
-            if (_offset == 16)
+            if (this._offset == 16)
             {
             {
                 ProcessBlock();
                 ProcessBlock();
             }
             }
@@ -166,13 +172,13 @@ namespace Renci.SshNet.Security.Cryptography
 
 
         private void ProcessLength(long bitLength)
         private void ProcessLength(long bitLength)
         {
         {
-            if (_offset > 14)
+            if (this._offset > 14)
             {
             {
                 ProcessBlock();
                 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)
         private void UnpackWord(int word, byte[] outBytes, int outOff)
@@ -185,15 +191,15 @@ namespace Renci.SshNet.Security.Cryptography
 
 
         private void Update(byte input)
         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>
         /// <summary>
@@ -201,9 +207,12 @@ namespace Renci.SshNet.Security.Cryptography
         /// </summary>
         /// </summary>
         private void InternalInitialize()
         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);
             H0 = unchecked((int)0x67452301);
             H1 = unchecked((int)0xefcdab89);
             H1 = unchecked((int)0xefcdab89);
@@ -211,11 +220,11 @@ namespace Renci.SshNet.Security.Cryptography
             H3 = unchecked((int)0x10325476);
             H3 = unchecked((int)0x10325476);
             H4 = unchecked((int)0xc3d2e1f0);
             H4 = unchecked((int)0xc3d2e1f0);
 
 
-            _offset = 0;
+            this._offset = 0;
 
 
             for (int i = 0; i != X.Length; i++)
             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
             // Rounds 1 - 16
             //
             //
             // left
             // 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
             // 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
             // Rounds 16-31
             //
             //
             // left
             // 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
             // 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
             // Rounds 32-47
             //
             //
             // left
             // 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
             // 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
             // Rounds 48-63
             //
             //
             // left
             // 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
             // 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
             // Rounds 64-79
             //
             //
             // left
             // 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
             // 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;
             dd += c + H1;
             H1 = H2 + d + ee;
             H1 = H2 + d + ee;
@@ -503,10 +512,10 @@ namespace Renci.SshNet.Security.Cryptography
             //
             //
             // reset the offset and clean out the word buffer.
             // 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>
 	/// <summary>
 	/// SHA1 algorithm implementation
 	/// SHA1 algorithm implementation
 	/// </summary>
 	/// </summary>
-	public class SHA1Hash : HashAlgorithm
+	public sealed class SHA1Hash : HashAlgorithm
 	{
 	{
 		private const int DIGEST_SIZE = 20;
 		private const int DIGEST_SIZE = 20;
 
 
@@ -159,17 +159,17 @@ namespace Renci.SshNet.Security.Cryptography
 				this.ProcessBlock();
 				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();
 			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();
             this.Initialize();
 
 
@@ -186,9 +186,13 @@ namespace Renci.SshNet.Security.Cryptography
 
 
         private void InternalInitialize()
         private void InternalInitialize()
         {
         {
+            var i = 0;
             this._byteCount = 0;
             this._byteCount = 0;
             this._bufferOffset = 0;
             this._bufferOffset = 0;
-            Array.Clear(this._buffer, 0, this._buffer.Length);
+            for (i = 0; i < 4; i++)
+            {
+                this._buffer[i] = 0;
+            }
 
 
             H1 = 0x67452301;
             H1 = 0x67452301;
             H2 = 0xefcdab89;
             H2 = 0xefcdab89;
@@ -197,7 +201,10 @@ namespace Renci.SshNet.Security.Cryptography
             H5 = 0xc3d2e1f0;
             H5 = 0xc3d2e1f0;
 
 
             this._offset = 0;
             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)
 		private void Update(byte input)
@@ -215,7 +222,7 @@ namespace Renci.SshNet.Security.Cryptography
 
 
 		private void ProcessWord(byte[] input, int inOff)
 		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)
 			if (++this._offset == 16)
 			{
 			{
@@ -263,94 +270,272 @@ namespace Renci.SshNet.Security.Cryptography
 			//
 			//
 			int idx = 0;
 			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
 			// 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
 			// 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
 			// 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;
 			H1 += A;
 			H2 += B;
 			H2 += B;
@@ -362,10 +547,13 @@ namespace Renci.SshNet.Security.Cryptography
 			// reset start of the buffer.
 			// reset start of the buffer.
 			//
 			//
 			this._offset = 0;
 			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;
 			uint n = (uint)bs[off] << 24;
 			n |= (uint)bs[++off] << 16;
 			n |= (uint)bs[++off] << 16;
@@ -374,8 +562,7 @@ namespace Renci.SshNet.Security.Cryptography
 			return n;
 			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 >> 24);
 			bs[++off] = (byte)(n >> 16);
 			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._byteCount = 0;
             this._bufferOffset = 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;
             H1 = 0x6a09e667;
             H2 = 0xbb67ae85;
             H2 = 0xbb67ae85;
@@ -198,7 +201,10 @@ namespace Renci.SshNet.Security.Cryptography
             H8 = 0x5be0cd19;
             H8 = 0x5be0cd19;
 
 
             this._offset = 0;
             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)
 		private void Update(byte input)
@@ -339,7 +345,10 @@ namespace Renci.SshNet.Security.Cryptography
 			// reset the offset and clean out the word buffer.
 			// reset the offset and clean out the word buffer.
 			//
 			//
 			this._offset = 0;
 			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)
 		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);
 			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 = {
 		private static readonly uint[] K = {
 			0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
 			0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
 			0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
 			0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -388,6 +396,5 @@ namespace Renci.SshNet.Security.Cryptography
 			0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
 			0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
 			0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 			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;
             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()
         protected void Finish()
@@ -242,7 +245,10 @@ namespace Renci.SshNet.Security.Cryptography
             // reset the offset and clean out the word buffer.
             // reset the offset and clean out the word buffer.
             //
             //
             this._offset = 0;
             this._offset = 0;
-            Array.Clear(X, 0, 16);
+            for (int i = 0; i < this.X.Length; i++)
+            {
+                this.X[i] = 0;
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>