+2002-11-15 Sebastien Pouliot <spouliot@videotron.ca>
+
+ * CryptographicUnexpectedOperationException.cs: Forgot it last time!
+ * FromBase64Transform.cs: Added missing virtual to CanReuseTransform.
+ Changed Dispose().
+ * HashAlgorithm.cs: Changed Dispose().
+ * MD5CryptoServiceProvider.cs: Added destructor and Dipose(bool).
+ * PasswordDeriveBytes.cs: Changed some declaration from
+ protected to private.
+ * RC2.cs: Added valid keysize check in EffectiveKeySize.
+ * RC2CryptoServiceProvider.cs: Overriden EffectiveKeySize to match
+ corlib declarations.
+ * RSAOAEPKeyExchangeDeformatter.cs: Changed some declaration from
+ protected to private.
+ * RSAOAEPKeyExchangeFormatter.cs: Changed some declaration from
+ protected to private.
+ * RSAPKCS1KeyExchangeDeformatter.cs: Changed some declaration from
+ protected to private.
+ * RSAPKCS1KeyExchangeFormatter.cs: Changed some declaration from
+ protected to private.
+ * RSAPKCS1SignatureDeformatter.cs: Changed some declaration from
+ protected to private.
+ * RSAPKCS1SignatureFormatter.cs: Changed some declaration from
+ protected to private.
+ * SHA1CryptoServiceProvider.cs: Moved SHA1 code to SHA1Internal.
+ SHA1CryptoServiceProvider now use SHA1Internal. Added Dispose and
+ destructor.
+ * SHA1Managed.cs: New. Use SHA1Internal. Same as
+ SHA1CryptoServiceProvider but is required for binary compatibility.
+ * SHA256Managed.cs: Changed some declaration from protected to private.
+ * SHA384Managed.cs: Changed some declaration from protected to private.
+ * SHA512Managed.cs: Changed some declaration from protected to private.
+ * SymmetricAlgorithm.cs: Added Clear(), changed Dispose() and added
+ virtual to Dispose(bool).
+ * ToBase64Transform.cs: Added missing virtual to CanReuseTransform.
+ Changed Dispose().
+ * TripleDESCryptoServiceProvider.cs: Added missing sealed to class
+ declaration.
+
2002-11-03 Sebastien Pouliot <spouliot@videotron.ca>
* CryptoAPITransform.cs: Added missing CanReuseTransform property,
-//\r
-// System.Security.Cryptography.CryptographicUnexpectedOperationException.cs\r
-//\r
-// Author:\r
-// Thomas Neidhart (tome@sbox.tugraz.at)\r
-//\r
-\r
-using System;\r
-\r
-namespace System.Security.Cryptography {\r
-\r
- [Serializable]\r
- public class CryptographicUnexpectedOperationException : CryptographicException {\r
- // Constructors\r
- public CryptographicUnexpectedOperationException ()\r
- : base ("Error occured during a cryptographic operation.")\r
- {\r
- }\r
-\r
- public CryptographicUnexpectedOperationException (string message)\r
- : base (message)\r
- {\r
- }\r
-\r
- public CryptographicUnexpectedOperationException (string message, Exception inner)\r
- : base (message, inner)\r
- {\r
- }\r
-\r
- public CryptographicUnexpectedOperationException (string format, string insert)\r
- : base (String.Format(format, insert))\r
- {\r
- }\r
- }\r
-}\r
+//
+// System.Security.Cryptography.CryptographicUnexpectedOperationException.cs
+//
+// Author:
+// Thomas Neidhart (tome@sbox.tugraz.at)
+//
+
+using System;
+using System.Runtime.Serialization;
+
+namespace System.Security.Cryptography {
+
+[Serializable]
+public class CryptographicUnexpectedOperationException : CryptographicException {
+ // Constructors
+ public CryptographicUnexpectedOperationException ()
+ : base ("Error occured during a cryptographic operation.")
+ {
+ }
+
+ public CryptographicUnexpectedOperationException (string message)
+ : base (message)
+ {
+ }
+
+ public CryptographicUnexpectedOperationException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+
+ public CryptographicUnexpectedOperationException (string format, string insert)
+ : base (String.Format(format, insert))
+ {
+ }
+
+ protected CryptographicUnexpectedOperationException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+}
+
+}
}
}
- public bool CanReuseTransform {
+ public virtual bool CanReuseTransform {
get { return false; }
}
Dispose (true);
}
- public void Dispose ()
+ void IDisposable.Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this); // Finalization is now unnecessary
-//\r
-// System.Security.Cryptography HashAlgorithm Class implementation\r
-//\r
-// Authors:\r
-// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)\r
-// Sebastien Pouliot (spouliot@motus.com)\r
-//\r
-// Copyright 2001 by Matthew S. Ford.\r
-// Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)\r
-//\r
-\r
-using System.IO;\r
-using System.Security.Cryptography;\r
-\r
-namespace System.Security.Cryptography {\r
- public abstract class HashAlgorithm : ICryptoTransform {\r
- protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.\r
- protected int HashSizeValue; // The size of the hash in bits.\r
- protected int State; // nonzero when in use; zero when not in use\r
- private bool disposed;\r
-\r
- /// <summary>\r
- /// Called from constructor of derived class.\r
- /// </summary>\r
- protected HashAlgorithm () \r
- {\r
- disposed = false;\r
- }\r
-\r
- // important so we can destory any unmanaged resources\r
- ~HashAlgorithm () \r
- {\r
- Dispose (true);\r
- }\r
- \r
- /// <summary>\r
- /// Get whether or not the hash can transform multiple blocks at a time.\r
- /// Note: MUST be overriden if descendant can transform multiple block\r
- /// on a single call!\r
- /// </summary>\r
- public virtual bool CanTransformMultipleBlocks {\r
- get { return true; }\r
- }\r
-\r
- public virtual bool CanReuseTransform {\r
- get { return true; }\r
- }\r
-\r
- public void Clear() \r
- {\r
- // same as System.IDisposable.Dispose() which is documented\r
- Dispose (true);\r
- }\r
-\r
- /// <summary>\r
- /// Computes the entire hash of all the bytes in the byte array.\r
- /// </summary>\r
- public byte[] ComputeHash (byte[] input) \r
- {\r
- return ComputeHash (input, 0, input.Length);\r
- }\r
-\r
- public byte[] ComputeHash (byte[] buffer, int offset, int count) \r
- {\r
- if (disposed)\r
- throw new ObjectDisposedException ("HashAlgorithm");\r
-\r
- HashCore (buffer, offset, count);\r
- HashValue = HashFinal ();\r
- Initialize ();\r
- \r
- return HashValue;\r
- }\r
-\r
- public byte[] ComputeHash (Stream inputStream) \r
- {\r
- // don't read stream unless object is ready to use\r
- if (disposed)\r
- throw new ObjectDisposedException ("HashAlgorithm");\r
-\r
- int l = (int) (inputStream.Length - inputStream.Position);\r
- byte[] buffer = new byte [l];\r
- inputStream.Read (buffer, 0, l);\r
-\r
- return ComputeHash (buffer);\r
- }\r
- \r
- /// <summary>\r
- /// Creates the default implementation of the default hash algorithm (SHA1).\r
- /// </summary>\r
- public static HashAlgorithm Create () \r
- {\r
- return Create ("System.Security.Cryptography.HashAlgorithm");\r
- }\r
- \r
- /// <summary>\r
- /// Creates a specific implementation of the general hash idea.\r
- /// </summary>\r
- /// <param name="hashName">Specifies which derived class to create.</param>\r
- public static HashAlgorithm Create (string hashName)\r
- {\r
- return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);\r
- }\r
- \r
- /// <summary>\r
- /// Gets the previously computed hash.\r
- /// </summary>\r
- public virtual byte[] Hash {\r
- get { \r
- if (HashValue == null)\r
- throw new CryptographicUnexpectedOperationException ();\r
- return HashValue; \r
- }\r
- }\r
- \r
- /// <summary>\r
- /// When overridden in a derived class, drives the hashing function.\r
- /// </summary>\r
- /// <param name="rgb"></param>\r
- /// <param name="start"></param>\r
- /// <param name="size"></param>\r
- protected abstract void HashCore (byte[] rgb, int start, int size);\r
-\r
- /// <summary>\r
- /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.\r
- /// </summary>\r
- protected abstract byte[] HashFinal ();\r
-\r
- /// <summary>\r
- /// Returns the size in bits of the hash.\r
- /// </summary>\r
- public virtual int HashSize {\r
- get { return HashSizeValue; }\r
- }\r
- \r
- /// <summary>\r
- /// When overridden in a derived class, initializes the object to prepare for hashing.\r
- /// </summary>\r
- public abstract void Initialize ();\r
-\r
- protected virtual void Dispose (bool disposing)\r
- {\r
- disposed = true;\r
- }\r
- \r
- /// <summary>\r
- /// Must be overriden if not 1\r
- /// </summary>\r
- public virtual int InputBlockSize {\r
- get { return 1; }\r
- }\r
- \r
- /// <summary>\r
- /// Must be overriden if not 1\r
- /// </summary>\r
- public virtual int OutputBlockSize {\r
- get { return 1; }\r
- }\r
-\r
- void System.IDisposable.Dispose () \r
- {\r
- Dispose (true);\r
- }\r
- \r
- /// <summary>\r
- /// Used for stream chaining. Computes hash as data passes through it.\r
- /// </summary>\r
- /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>\r
- /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>\r
- /// <param name="inputCount">The number of bytes to be copied.</param>\r
- /// <param name="outputBuffer">The buffer to write the copied data to.</param>\r
- /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>\r
- public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) \r
- {\r
- Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);\r
- HashCore (inputBuffer, inputOffset, inputCount);\r
-\r
- return inputCount;\r
- }\r
- \r
- /// <summary>\r
- /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.\r
- /// </summary>\r
- /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>\r
- /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>\r
- /// <param name="inputCount">The number of bytes to be copied.</param>\r
- public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) \r
- {\r
- byte[] outputBuffer = new byte[inputCount];\r
- \r
- Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);\r
- \r
- HashCore (inputBuffer, inputOffset, inputCount);\r
- HashValue = HashFinal ();\r
- Initialize ();\r
- \r
- return outputBuffer;\r
- }\r
- }\r
-}\r
-\r
+//
+// System.Security.Cryptography HashAlgorithm Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+// Sebastien Pouliot (spouliot@motus.com)
+//
+// Copyright 2001 by Matthew S. Ford.
+// Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
+//
+
+using System.IO;
+
+namespace System.Security.Cryptography {
+ public abstract class HashAlgorithm : ICryptoTransform {
+ protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
+ protected int HashSizeValue; // The size of the hash in bits.
+ protected int State; // nonzero when in use; zero when not in use
+ private bool disposed;
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected HashAlgorithm ()
+ {
+ disposed = false;
+ }
+
+ // important so we can destory any unmanaged resources
+ ~HashAlgorithm ()
+ {
+ Dispose (true);
+ }
+
+ /// <summary>
+ /// Get whether or not the hash can transform multiple blocks at a time.
+ /// Note: MUST be overriden if descendant can transform multiple block
+ /// on a single call!
+ /// </summary>
+ public virtual bool CanTransformMultipleBlocks {
+ get { return true; }
+ }
+
+ public virtual bool CanReuseTransform {
+ get { return true; }
+ }
+
+ public void Clear()
+ {
+ // same as System.IDisposable.Dispose() which is documented
+ Dispose (true);
+ }
+
+ /// <summary>
+ /// Computes the entire hash of all the bytes in the byte array.
+ /// </summary>
+ public byte[] ComputeHash (byte[] input)
+ {
+ return ComputeHash (input, 0, input.Length);
+ }
+
+ public byte[] ComputeHash (byte[] buffer, int offset, int count)
+ {
+ if (disposed)
+ throw new ObjectDisposedException ("HashAlgorithm");
+
+ HashCore (buffer, offset, count);
+ HashValue = HashFinal ();
+ Initialize ();
+
+ return HashValue;
+ }
+
+ public byte[] ComputeHash (Stream inputStream)
+ {
+ // don't read stream unless object is ready to use
+ if (disposed)
+ throw new ObjectDisposedException ("HashAlgorithm");
+
+ int l = (int) (inputStream.Length - inputStream.Position);
+ byte[] buffer = new byte [l];
+ inputStream.Read (buffer, 0, l);
+
+ return ComputeHash (buffer, 0, l);
+ }
+
+ /// <summary>
+ /// Creates the default implementation of the default hash algorithm (SHA1).
+ /// </summary>
+ public static HashAlgorithm Create ()
+ {
+ return Create ("System.Security.Cryptography.HashAlgorithm");
+ }
+
+ /// <summary>
+ /// Creates a specific implementation of the general hash idea.
+ /// </summary>
+ /// <param name="hashName">Specifies which derived class to create.</param>
+ public static HashAlgorithm Create (string hashName)
+ {
+ return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
+ }
+
+ /// <summary>
+ /// Gets the previously computed hash.
+ /// </summary>
+ public virtual byte[] Hash {
+ get {
+ if (HashValue == null)
+ throw new CryptographicUnexpectedOperationException ();
+ return HashValue;
+ }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, drives the hashing function.
+ /// </summary>
+ /// <param name="rgb"></param>
+ /// <param name="start"></param>
+ /// <param name="size"></param>
+ protected abstract void HashCore (byte[] rgb, int start, int size);
+
+ /// <summary>
+ /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
+ /// </summary>
+ protected abstract byte[] HashFinal ();
+
+ /// <summary>
+ /// Returns the size in bits of the hash.
+ /// </summary>
+ public virtual int HashSize {
+ get { return HashSizeValue; }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, initializes the object to prepare for hashing.
+ /// </summary>
+ public abstract void Initialize ();
+
+ protected virtual void Dispose (bool disposing)
+ {
+ disposed = true;
+ }
+
+ /// <summary>
+ /// Must be overriden if not 1
+ /// </summary>
+ public virtual int InputBlockSize {
+ get { return 1; }
+ }
+
+ /// <summary>
+ /// Must be overriden if not 1
+ /// </summary>
+ public virtual int OutputBlockSize {
+ get { return 1; }
+ }
+
+ void IDisposable.Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this); // Finalization is now unnecessary
+ }
+
+ /// <summary>
+ /// Used for stream chaining. Computes hash as data passes through it.
+ /// </summary>
+ /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
+ /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
+ /// <param name="inputCount">The number of bytes to be copied.</param>
+ /// <param name="outputBuffer">The buffer to write the copied data to.</param>
+ /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
+ public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
+ HashCore (inputBuffer, inputOffset, inputCount);
+
+ return inputCount;
+ }
+
+ /// <summary>
+ /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
+ /// </summary>
+ /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
+ /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
+ /// <param name="inputCount">The number of bytes to be copied.</param>
+ public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ byte[] outputBuffer = new byte[inputCount];
+
+ Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
+
+ HashCore (inputBuffer, inputOffset, inputCount);
+ HashValue = HashFinal ();
+ Initialize ();
+
+ return outputBuffer;
+ }
+ }
+}
+
-//\r
-// System.Security.Cryptography MD5CryptoServiceProvider Class implementation\r
-//\r
-// Authors:\r
-// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)\r
-//\r
-// Copyright 2001 by Matthew S. Ford.\r
-//\r
-\r
-\r
-using System.Security.Cryptography;\r
-\r
-namespace System.Security.Cryptography {\r
-\r
- /// <summary>\r
- /// C# implementation of the MD5 cryptographic hash function.\r
- /// </summary>\r
- public class MD5CryptoServiceProvider : MD5 {\r
- private const int BLOCK_SIZE_BYTES = 64;\r
- private const int HASH_SIZE_BYTES = 16;\r
- private const int HASH_SIZE_BITS = 128;\r
- [CLSCompliant(false)] protected uint[] _H;\r
- [CLSCompliant(false)] protected uint count;\r
- private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.\r
- private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.\r
- \r
- /// <summary>\r
- /// Creates a new MD5CryptoServiceProvider.\r
- /// </summary>\r
- public MD5CryptoServiceProvider () {\r
- _H = new uint[4];\r
- HashSizeValue = HASH_SIZE_BITS;\r
- _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];\r
-\r
- Initialize();\r
- }\r
-\r
- /// <summary>\r
- /// Drives the hashing function.\r
- /// </summary>\r
- /// <param name="rgb">Byte array containing the data to hash.</param>\r
- /// <param name="start">Where in the input buffer to start.</param>\r
- /// <param name="size">Size in bytes of the data in the buffer to hash.</param>\r
- protected override void HashCore (byte[] rgb, int start, int size) {\r
- int i;\r
- State = 1;\r
-\r
- if (_ProcessingBufferCount != 0) {\r
- if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {\r
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);\r
- _ProcessingBufferCount += size;\r
- return;\r
- }\r
- else {\r
- i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);\r
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);\r
- ProcessBlock (_ProcessingBuffer, 0);\r
- _ProcessingBufferCount = 0;\r
- start += i;\r
- size -= i;\r
- }\r
- }\r
-\r
- for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {\r
- ProcessBlock (rgb, start+i);\r
- }\r
-\r
- if (size%BLOCK_SIZE_BYTES != 0) {\r
- System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);\r
- _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;\r
- }\r
- }\r
- \r
- /// <summary>\r
- /// This finalizes the hash. Takes the data from the chaining variables and returns it.\r
- /// </summary>\r
- protected override byte[] HashFinal () {\r
- byte[] hash = new byte[16];\r
- int i, j;\r
-\r
- ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);\r
-\r
- for (i=0; i<4; i++) {\r
- for (j=0; j<4; j++) {\r
- hash[i*4+j] = (byte)(_H[i] >> j*8);\r
- }\r
- }\r
-\r
- return hash;\r
- }\r
-\r
- /// <summary>\r
- /// Resets the class after use. Called automatically after hashing is done.\r
- /// </summary>\r
- public override void Initialize () {\r
- count = 0;\r
- _ProcessingBufferCount = 0;\r
-\r
- _H[0] = 0x67452301;\r
- _H[1] = 0xefcdab89;\r
- _H[2] = 0x98badcfe;\r
- _H[3] = 0x10325476;\r
- }\r
-\r
- /// <summary>\r
- /// This is the meat of the hash function. It is what processes each block one at a time.\r
- /// </summary>\r
- /// <param name="inputBuffer">Byte array to process data from.</param>\r
- /// <param name="inputOffset">Where in the byte array to start processing.</param>\r
- private void ProcessBlock(byte[] inputBuffer, int inputOffset) {\r
- uint[] buff = new uint[16];\r
- uint a, b, c, d;\r
- int i;\r
- \r
- count += BLOCK_SIZE_BYTES;\r
- \r
- for (i=0; i<16; i++) {\r
- buff[i] = (uint)(inputBuffer[inputOffset+4*i])\r
- | (((uint)(inputBuffer[inputOffset+4*i+1])) << 8)\r
- | (((uint)(inputBuffer[inputOffset+4*i+2])) << 16)\r
- | (((uint)(inputBuffer[inputOffset+4*i+3])) << 24);\r
- }\r
- \r
- a = _H[0];\r
- b = _H[1];\r
- c = _H[2];\r
- d = _H[3];\r
- \r
- // This function was unrolled because it seems to be doubling our performance with current compiler/VM.\r
- // Possibly roll up if this changes.\r
-\r
-\r
- // ---- Round 1 --------\r
-\r
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C0 + buff [0];\r
- a = (a << 7) | (a >> 25);\r
- a += b;\r
-\r
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C1 + buff [1];\r
- d = (d << 12) | (d >> 20);\r
- d += a;\r
-\r
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C2 + buff [2];\r
- c = (c << 17) | (c >> 15);\r
- c += d;\r
-\r
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C3 + buff [3];\r
- b = (b << 22) | (b >> 10);\r
- b += c;\r
-\r
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C4 + buff [4];\r
- a = (a << 7) | (a >> 25);\r
- a += b;\r
-\r
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C5 + buff [5];\r
- d = (d << 12) | (d >> 20);\r
- d += a;\r
-\r
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C6 + buff [6];\r
- c = (c << 17) | (c >> 15);\r
- c += d;\r
-\r
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C7 + buff [7];\r
- b = (b << 22) | (b >> 10);\r
- b += c;\r
-\r
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C8 + buff [8];\r
- a = (a << 7) | (a >> 25);\r
- a += b;\r
-\r
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C9 + buff [9];\r
- d = (d << 12) | (d >> 20);\r
- d += a;\r
-\r
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C10 + buff [10];\r
- c = (c << 17) | (c >> 15);\r
- c += d;\r
-\r
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C11 + buff [11];\r
- b = (b << 22) | (b >> 10);\r
- b += c;\r
-\r
- a += (((c ^ d) & b) ^ d) + (uint) Constants.C12 + buff [12];\r
- a = (a << 7) | (a >> 25);\r
- a += b;\r
-\r
- d += (((b ^ c) & a) ^ c) + (uint) Constants.C13 + buff [13];\r
- d = (d << 12) | (d >> 20);\r
- d += a;\r
-\r
- c += (((a ^ b) & d) ^ b) + (uint) Constants.C14 + buff [14];\r
- c = (c << 17) | (c >> 15);\r
- c += d;\r
-\r
- b += (((d ^ a) & c) ^ a) + (uint) Constants.C15 + buff [15];\r
- b = (b << 22) | (b >> 10);\r
- b += c;\r
-\r
-\r
- // ---- Round 2 --------\r
- \r
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C16 + buff [1];\r
- a = (a << 5) | (a >> 27);\r
- a += b;\r
-\r
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C17 + buff [6];\r
- d = (d << 9) | (d >> 23);\r
- d += a;\r
-\r
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C18 + buff [11];\r
- c = (c << 14) | (c >> 18);\r
- c += d;\r
-\r
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C19 + buff [0];\r
- b = (b << 20) | (b >> 12);\r
- b += c;\r
-\r
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C20 + buff [5];\r
- a = (a << 5) | (a >> 27);\r
- a += b;\r
-\r
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C21 + buff [10];\r
- d = (d << 9) | (d >> 23);\r
- d += a;\r
-\r
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C22 + buff [15];\r
- c = (c << 14) | (c >> 18);\r
- c += d;\r
-\r
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C23 + buff [4];\r
- b = (b << 20) | (b >> 12);\r
- b += c;\r
-\r
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C24 + buff [9];\r
- a = (a << 5) | (a >> 27);\r
- a += b;\r
-\r
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C25 + buff [14];\r
- d = (d << 9) | (d >> 23);\r
- d += a;\r
-\r
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C26 + buff [3];\r
- c = (c << 14) | (c >> 18);\r
- c += d;\r
-\r
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C27 + buff [8];\r
- b = (b << 20) | (b >> 12);\r
- b += c;\r
-\r
- a += (((b ^ c) & d) ^ c) + (uint) Constants.C28 + buff [13];\r
- a = (a << 5) | (a >> 27);\r
- a += b;\r
-\r
- d += (((a ^ b) & c) ^ b) + (uint) Constants.C29 + buff [2];\r
- d = (d << 9) | (d >> 23);\r
- d += a;\r
-\r
- c += (((d ^ a) & b) ^ a) + (uint) Constants.C30 + buff [7];\r
- c = (c << 14) | (c >> 18);\r
- c += d;\r
-\r
- b += (((c ^ d) & a) ^ d) + (uint) Constants.C31 + buff [12];\r
- b = (b << 20) | (b >> 12);\r
- b += c;\r
-\r
-\r
- // ---- Round 3 --------\r
- \r
- a += (b ^ c ^ d) + (uint) Constants.C32 + buff [5];\r
- a = (a << 4) | (a >> 28);\r
- a += b;\r
-\r
- d += (a ^ b ^ c) + (uint) Constants.C33 + buff [8];\r
- d = (d << 11) | (d >> 21);\r
- d += a;\r
-\r
- c += (d ^ a ^ b) + (uint) Constants.C34 + buff [11];\r
- c = (c << 16) | (c >> 16);\r
- c += d;\r
-\r
- b += (c ^ d ^ a) + (uint) Constants.C35 + buff [14];\r
- b = (b << 23) | (b >> 9);\r
- b += c;\r
-\r
- a += (b ^ c ^ d) + (uint) Constants.C36 + buff [1];\r
- a = (a << 4) | (a >> 28);\r
- a += b;\r
-\r
- d += (a ^ b ^ c) + (uint) Constants.C37 + buff [4];\r
- d = (d << 11) | (d >> 21);\r
- d += a;\r
-\r
- c += (d ^ a ^ b) + (uint) Constants.C38 + buff [7];\r
- c = (c << 16) | (c >> 16);\r
- c += d;\r
-\r
- b += (c ^ d ^ a) + (uint) Constants.C39 + buff [10];\r
- b = (b << 23) | (b >> 9);\r
- b += c;\r
-\r
- a += (b ^ c ^ d) + (uint) Constants.C40 + buff [13];\r
- a = (a << 4) | (a >> 28);\r
- a += b;\r
-\r
- d += (a ^ b ^ c) + (uint) Constants.C41 + buff [0];\r
- d = (d << 11) | (d >> 21);\r
- d += a;\r
-\r
- c += (d ^ a ^ b) + (uint) Constants.C42 + buff [3];\r
- c = (c << 16) | (c >> 16);\r
- c += d;\r
-\r
- b += (c ^ d ^ a) + (uint) Constants.C43 + buff [6];\r
- b = (b << 23) | (b >> 9);\r
- b += c;\r
-\r
- a += (b ^ c ^ d) + (uint) Constants.C44 + buff [9];\r
- a = (a << 4) | (a >> 28);\r
- a += b;\r
-\r
- d += (a ^ b ^ c) + (uint) Constants.C45 + buff [12];\r
- d = (d << 11) | (d >> 21);\r
- d += a;\r
-\r
- c += (d ^ a ^ b) + (uint) Constants.C46 + buff [15];\r
- c = (c << 16) | (c >> 16);\r
- c += d;\r
-\r
- b += (c ^ d ^ a) + (uint) Constants.C47 + buff [2];\r
- b = (b << 23) | (b >> 9);\r
- b += c;\r
-\r
-\r
- // ---- Round 4 --------\r
- \r
- a += (((~d) | b) ^ c) + (uint) Constants.C48 + buff [0];\r
- a = (a << 6) | (a >> 26);\r
- a += b;\r
-\r
- d += (((~c) | a) ^ b) + (uint) Constants.C49 + buff [7];\r
- d = (d << 10) | (d >> 22);\r
- d += a;\r
-\r
- c += (((~b) | d) ^ a) + (uint) Constants.C50 + buff [14];\r
- c = (c << 15) | (c >> 17);\r
- c += d;\r
-\r
- b += (((~a) | c) ^ d) + (uint) Constants.C51 + buff [5];\r
- b = (b << 21) | (b >> 11);\r
- b += c;\r
-\r
- a += (((~d) | b) ^ c) + (uint) Constants.C52 + buff [12];\r
- a = (a << 6) | (a >> 26);\r
- a += b;\r
-\r
- d += (((~c) | a) ^ b) + (uint) Constants.C53 + buff [3];\r
- d = (d << 10) | (d >> 22);\r
- d += a;\r
-\r
- c += (((~b) | d) ^ a) + (uint) Constants.C54 + buff [10];\r
- c = (c << 15) | (c >> 17);\r
- c += d;\r
-\r
- b += (((~a) | c) ^ d) + (uint) Constants.C55 + buff [1];\r
- b = (b << 21) | (b >> 11);\r
- b += c;\r
-\r
- a += (((~d) | b) ^ c) + (uint) Constants.C56 + buff [8];\r
- a = (a << 6) | (a >> 26);\r
- a += b;\r
-\r
- d += (((~c) | a) ^ b) + (uint) Constants.C57 + buff [15];\r
- d = (d << 10) | (d >> 22);\r
- d += a;\r
-\r
- c += (((~b) | d) ^ a) + (uint) Constants.C58 + buff [6];\r
- c = (c << 15) | (c >> 17);\r
- c += d;\r
-\r
- b += (((~a) | c) ^ d) + (uint) Constants.C59 + buff [13];\r
- b = (b << 21) | (b >> 11);\r
- b += c;\r
-\r
- a += (((~d) | b) ^ c) + (uint) Constants.C60 + buff [4];\r
- a = (a << 6) | (a >> 26);\r
- a += b;\r
-\r
- d += (((~c) | a) ^ b) + (uint) Constants.C61 + buff [11];\r
- d = (d << 10) | (d >> 22);\r
- d += a;\r
-\r
- c += (((~b) | d) ^ a) + (uint) Constants.C62 + buff [2];\r
- c = (c << 15) | (c >> 17);\r
- c += d;\r
-\r
- b += (((~a) | c) ^ d) + (uint) Constants.C63 + buff [9];\r
- b = (b << 21) | (b >> 11);\r
- b += c;\r
-\r
-\r
- _H[0] += a;\r
- _H[1] += b;\r
- _H[2] += c;\r
- _H[3] += d;\r
- }\r
- \r
- /// <summary>\r
- /// Pads and then processes the final block.\r
- /// </summary>\r
- /// <param name="inputBuffer">Buffer to grab data from.</param>\r
- /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>\r
- /// <param name="inputCount">How much data in bytes in the buffer to use.</param>\r
- private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {\r
- byte[] fooBuffer;\r
- int paddingSize;\r
- int i;\r
- uint size;\r
-\r
- paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);\r
-\r
- if (paddingSize < 1)\r
- paddingSize += BLOCK_SIZE_BYTES;\r
-\r
-\r
- fooBuffer = new byte[inputCount+paddingSize+8];\r
-\r
- for (i=0; i<inputCount; i++) {\r
- fooBuffer[i] = inputBuffer[i+inputOffset];\r
- }\r
-\r
- fooBuffer[inputCount] = 0x80;\r
- for (i=inputCount+1; i<inputCount+paddingSize; i++) {\r
- fooBuffer[i] = 0x00;\r
- }\r
-\r
- size = (uint)(count+inputCount);\r
- size *= 8;\r
- fooBuffer[inputCount+paddingSize] = (byte)((size) >> 0);\r
- fooBuffer[inputCount+paddingSize+1] = (byte)((size) >> 8);\r
- fooBuffer[inputCount+paddingSize+2] = (byte)((size) >> 16);\r
- fooBuffer[inputCount+paddingSize+3] = (byte)((size) >> 24);\r
-\r
- fooBuffer[inputCount+paddingSize+4] = 0x00;\r
- fooBuffer[inputCount+paddingSize+5] = 0x00;\r
- fooBuffer[inputCount+paddingSize+6] = 0x00;\r
- fooBuffer[inputCount+paddingSize+7] = 0x00;\r
-\r
- ProcessBlock(fooBuffer, 0);\r
-\r
- if (inputCount+paddingSize+8 == 128) {\r
- ProcessBlock(fooBuffer, 64);\r
- }\r
- }\r
- \r
- private enum Constants : uint {\r
- C0 = 0xd76aa478, C1 = 0xe8c7b756, C2 = 0x242070db,\r
- C3 = 0xc1bdceee, C4 = 0xf57c0faf, C5 = 0x4787c62a,\r
- C6 = 0xa8304613, C7 = 0xfd469501, C8 = 0x698098d8,\r
- C9 = 0x8b44f7af,C10 = 0xffff5bb1,C11 = 0x895cd7be,\r
- C12 = 0x6b901122,C13 = 0xfd987193,C14 = 0xa679438e,\r
- C15 = 0x49b40821,C16 = 0xf61e2562,C17 = 0xc040b340,\r
- C18 = 0x265e5a51,C19 = 0xe9b6c7aa,C20 = 0xd62f105d,\r
- C21 = 0x02441453,C22 = 0xd8a1e681,C23 = 0xe7d3fbc8,\r
- C24 = 0x21e1cde6,C25 = 0xc33707d6,C26 = 0xf4d50d87,\r
- C27 = 0x455a14ed,C28 = 0xa9e3e905,C29 = 0xfcefa3f8,\r
- C30 = 0x676f02d9,C31 = 0x8d2a4c8a,C32 = 0xfffa3942,\r
- C33 = 0x8771f681,C34 = 0x6d9d6122,C35 = 0xfde5380c,\r
- C36 = 0xa4beea44,C37 = 0x4bdecfa9,C38 = 0xf6bb4b60,\r
- C39 = 0xbebfbc70,C40 = 0x289b7ec6,C41 = 0xeaa127fa,\r
- C42 = 0xd4ef3085,C43 = 0x04881d05,C44 = 0xd9d4d039,\r
- C45 = 0xe6db99e5,C46 = 0x1fa27cf8,C47 = 0xc4ac5665,\r
- C48 = 0xf4292244,C49 = 0x432aff97,C50 = 0xab9423a7,\r
- C51 = 0xfc93a039,C52 = 0x655b59c3,C53 = 0x8f0ccc92,\r
- C54 = 0xffeff47d,C55 = 0x85845dd1,C56 = 0x6fa87e4f,\r
- C57 = 0xfe2ce6e0,C58 = 0xa3014314,C59 = 0x4e0811a1,\r
- C60 = 0xf7537e82,C61 = 0xbd3af235,C62 = 0x2ad7d2bb,\r
- C63 = 0xeb86d391\r
- }\r
-\r
- }\r
-}\r
-\r
+//
+// System.Security.Cryptography MD5CryptoServiceProvider Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// C# implementation of the MD5 cryptographic hash function.
+ /// </summary>
+ public class MD5CryptoServiceProvider : MD5 {
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 16;
+ private const int HASH_SIZE_BITS = 128;
+ [CLSCompliant(false)] private uint[] _H;
+ [CLSCompliant(false)] private uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new MD5CryptoServiceProvider.
+ /// </summary>
+ public MD5CryptoServiceProvider ()
+ {
+ _H = new uint[4];
+ HashSizeValue = HASH_SIZE_BITS;
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ Initialize();
+ }
+
+ ~MD5CryptoServiceProvider ()
+ {
+ Dispose (false);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ // nothing to do (managed implementation)
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ protected override void HashCore (byte[] rgb, int start, int size)
+ {
+ int i;
+ State = 1;
+
+ if (_ProcessingBufferCount != 0) {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0) {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ protected override byte[] HashFinal ()
+ {
+ byte[] hash = new byte[16];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<4; j++) {
+ hash[i*4+j] = (byte)(_H[i] >> j*8);
+ }
+ }
+
+ return hash;
+ }
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public override void Initialize ()
+ {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x67452301;
+ _H[1] = 0xefcdab89;
+ _H[2] = 0x98badcfe;
+ _H[3] = 0x10325476;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ private void ProcessBlock (byte[] inputBuffer, int inputOffset)
+ {
+ uint[] buff = new uint[16];
+ uint a, b, c, d;
+ int i;
+
+ count += BLOCK_SIZE_BYTES;
+
+ for (i=0; i<16; i++) {
+ buff[i] = (uint)(inputBuffer[inputOffset+4*i])
+ | (((uint)(inputBuffer[inputOffset+4*i+1])) << 8)
+ | (((uint)(inputBuffer[inputOffset+4*i+2])) << 16)
+ | (((uint)(inputBuffer[inputOffset+4*i+3])) << 24);
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+
+ // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
+ // Possibly roll up if this changes.
+
+
+ // ---- Round 1 --------
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C0 + buff [0];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C1 + buff [1];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C2 + buff [2];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C3 + buff [3];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C4 + buff [4];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C5 + buff [5];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C6 + buff [6];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C7 + buff [7];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C8 + buff [8];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C9 + buff [9];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C10 + buff [10];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C11 + buff [11];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C12 + buff [12];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C13 + buff [13];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C14 + buff [14];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C15 + buff [15];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+
+ // ---- Round 2 --------
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C16 + buff [1];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C17 + buff [6];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C18 + buff [11];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C19 + buff [0];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C20 + buff [5];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C21 + buff [10];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C22 + buff [15];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C23 + buff [4];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C24 + buff [9];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C25 + buff [14];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C26 + buff [3];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C27 + buff [8];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C28 + buff [13];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C29 + buff [2];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C30 + buff [7];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C31 + buff [12];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+
+ // ---- Round 3 --------
+
+ a += (b ^ c ^ d) + (uint) Constants.C32 + buff [5];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C33 + buff [8];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C34 + buff [11];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C35 + buff [14];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C36 + buff [1];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C37 + buff [4];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C38 + buff [7];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C39 + buff [10];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C40 + buff [13];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C41 + buff [0];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C42 + buff [3];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C43 + buff [6];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C44 + buff [9];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C45 + buff [12];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C46 + buff [15];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C47 + buff [2];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+
+ // ---- Round 4 --------
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C48 + buff [0];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C49 + buff [7];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C50 + buff [14];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C51 + buff [5];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C52 + buff [12];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C53 + buff [3];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C54 + buff [10];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C55 + buff [1];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C56 + buff [8];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C57 + buff [15];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C58 + buff [6];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C59 + buff [13];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C60 + buff [4];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C61 + buff [11];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C62 + buff [2];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C63 + buff [9];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++) {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8;
+ fooBuffer[inputCount+paddingSize] = (byte)((size) >> 0);
+ fooBuffer[inputCount+paddingSize+1] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+2] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+3] = (byte)((size) >> 24);
+
+ fooBuffer[inputCount+paddingSize+4] = 0x00;
+ fooBuffer[inputCount+paddingSize+5] = 0x00;
+ fooBuffer[inputCount+paddingSize+6] = 0x00;
+ fooBuffer[inputCount+paddingSize+7] = 0x00;
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128) {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+
+ private enum Constants : uint {
+ C0 = 0xd76aa478, C1 = 0xe8c7b756, C2 = 0x242070db,
+ C3 = 0xc1bdceee, C4 = 0xf57c0faf, C5 = 0x4787c62a,
+ C6 = 0xa8304613, C7 = 0xfd469501, C8 = 0x698098d8,
+ C9 = 0x8b44f7af,C10 = 0xffff5bb1,C11 = 0x895cd7be,
+ C12 = 0x6b901122,C13 = 0xfd987193,C14 = 0xa679438e,
+ C15 = 0x49b40821,C16 = 0xf61e2562,C17 = 0xc040b340,
+ C18 = 0x265e5a51,C19 = 0xe9b6c7aa,C20 = 0xd62f105d,
+ C21 = 0x02441453,C22 = 0xd8a1e681,C23 = 0xe7d3fbc8,
+ C24 = 0x21e1cde6,C25 = 0xc33707d6,C26 = 0xf4d50d87,
+ C27 = 0x455a14ed,C28 = 0xa9e3e905,C29 = 0xfcefa3f8,
+ C30 = 0x676f02d9,C31 = 0x8d2a4c8a,C32 = 0xfffa3942,
+ C33 = 0x8771f681,C34 = 0x6d9d6122,C35 = 0xfde5380c,
+ C36 = 0xa4beea44,C37 = 0x4bdecfa9,C38 = 0xf6bb4b60,
+ C39 = 0xbebfbc70,C40 = 0x289b7ec6,C41 = 0xeaa127fa,
+ C42 = 0xd4ef3085,C43 = 0x04881d05,C44 = 0xd9d4d039,
+ C45 = 0xe6db99e5,C46 = 0x1fa27cf8,C47 = 0xc4ac5665,
+ C48 = 0xf4292244,C49 = 0x432aff97,C50 = 0xab9423a7,
+ C51 = 0xfc93a039,C52 = 0x655b59c3,C53 = 0x8f0ccc92,
+ C54 = 0xffeff47d,C55 = 0x85845dd1,C56 = 0x6fa87e4f,
+ C57 = 0xfe2ce6e0,C58 = 0xa3014314,C59 = 0x4e0811a1,
+ C60 = 0xf7537e82,C61 = 0xbd3af235,C62 = 0x2ad7d2bb,
+ C63 = 0xeb86d391
+ }
+
+ }
+}
+
public class PasswordDeriveBytes : DeriveBytes {
- protected string HashNameValue;
- protected string PasswordValue;
- protected byte[] SaltValue;
- protected int IterationsValue;
+ private string HashNameValue;
+ private string PasswordValue;
+ private byte[] SaltValue;
+ private int IterationsValue;
private HashAlgorithm hash;
private int state;
private byte[] output;
- private int posOut;
public PasswordDeriveBytes (string strPassword, byte[] rgbSalt)
{
hash = HashAlgorithm.Create (HashNameValue);
output = hash.ComputeHash (input);
- // we start serving key from the first byte
- posOut = 0;
}
}
-//\r
-// System.Security.Cryptography.RC2.cs\r
-//\r
-// Authors: Andrew Birkett (andy@nobugs.org)\r
-// \r
-\r
-using System;\r
-\r
-namespace System.Security.Cryptography {\r
-\r
- public abstract class RC2 : SymmetricAlgorithm {\r
-\r
- public static new RC2 Create () \r
- {\r
- return Create ("System.Security.Cryptography.RC2");\r
- }\r
- \r
- public static new RC2 Create (string algName) \r
- {\r
- return (RC2) CryptoConfig.CreateFromName (algName);\r
- }\r
-\r
- protected int EffectiveKeySizeValue;\r
- public virtual int EffectiveKeySize {\r
- get {\r
- if (EffectiveKeySizeValue == 0)\r
- return KeySizeValue;\r
- else\r
- return EffectiveKeySizeValue;\r
- }\r
- set { EffectiveKeySizeValue = value; }\r
- }\r
-\r
- // Overridden, which makes me suspect it changes effective keysize too?\r
- public override int KeySize {\r
- get { return KeySizeValue; }\r
- set { KeySizeValue = value; }\r
- }\r
- \r
- public RC2 () \r
- {\r
- KeySizeValue = 128;\r
- BlockSizeValue = 64;\r
- FeedbackSizeValue = 64;\r
-\r
- // The RFC allows keys of 1 to 128 bytes, but MS impl only supports\r
- // 40 to 128 bits, sigh.\r
- LegalKeySizesValue = new KeySizes[1];\r
- LegalKeySizesValue[0] = new KeySizes(40, 128, 8);\r
-\r
- LegalBlockSizesValue = new KeySizes[1];\r
- LegalBlockSizesValue[0] = new KeySizes(64, 64, 0);\r
- }\r
- }\r
-}\r
+//
+// System.Security.Cryptography.RC2.cs
+//
+// Authors:
+// Andrew Birkett (andy@nobugs.org)
+// Sebastien Pouliot (spouliot@motus.com)
+//
+
+using System;
+
+namespace System.Security.Cryptography {
+
+ public abstract class RC2 : SymmetricAlgorithm {
+
+ public static new RC2 Create ()
+ {
+ return Create ("System.Security.Cryptography.RC2");
+ }
+
+ public static new RC2 Create (string algName)
+ {
+ return (RC2) CryptoConfig.CreateFromName (algName);
+ }
+
+ protected int EffectiveKeySizeValue;
+
+ public virtual int EffectiveKeySize {
+ get {
+ if (EffectiveKeySizeValue == 0)
+ return KeySizeValue;
+ else
+ return EffectiveKeySizeValue;
+ }
+ set {
+ if (!IsLegalKeySize (LegalKeySizesValue, value))
+ throw new CryptographicException ("key size not supported by algorithm");
+ EffectiveKeySizeValue = value;
+ }
+ }
+
+ // Overridden, which makes me suspect it changes effective keysize too?
+ public override int KeySize {
+ get { return KeySizeValue; }
+ set { KeySizeValue = value; }
+ }
+
+ public RC2 ()
+ {
+ KeySizeValue = 128;
+ BlockSizeValue = 64;
+ FeedbackSizeValue = 64;
+
+ // The RFC allows keys of 1 to 128 bytes, but MS impl only supports
+ // 40 to 128 bits, sigh.
+ LegalKeySizesValue = new KeySizes[1];
+ LegalKeySizesValue[0] = new KeySizes(40, 128, 8);
+
+ LegalBlockSizesValue = new KeySizes[1];
+ LegalBlockSizesValue[0] = new KeySizes(64, 64, 0);
+ }
+ }
+}
-//
-// System.Security.Cryptography.RC2CryptoServiceProvider.cs
-//
-// Authors:
-// Andrew Birkett (andy@nobugs.org)
-// Sebastien Pouliot (spouliot@motus.com)
+//\r// System.Security.Cryptography.RC2CryptoServiceProvider.cs\r//\r// Authors:\r// Andrew Birkett (andy@nobugs.org)\r// Sebastien Pouliot (spouliot@motus.com)
//
// Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
-//
-
-using System;
-
-namespace System.Security.Cryptography {
-
-// References:
-// a. IETF RFC2286: A Description of the RC2(r) Encryption Algorithm
+// \r
+using System;\r
+namespace System.Security.Cryptography {\r
+// References:\r// a. IETF RFC2286: A Description of the RC2(r) Encryption Algorithm
// http://www.ietf.org/rfc/rfc2268.txt
-public sealed class RC2CryptoServiceProvider : RC2 {
-
- public RC2CryptoServiceProvider()
- {
- }
-
- public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
- {
- Key = rgbKey;
- IV = rgbIV;
- return new RC2Transform (this, false);
- }
-
- public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
- {
- Key = rgbKey;
- IV = rgbIV;
- return new RC2Transform (this, true);
- }
-
- [MonoTODO]
- public override void GenerateIV()
- {
- IVValue = new byte[BlockSizeValue / 8];
- for (int i=0; i < IVValue.Length; i++) IVValue[i] = 0;
- }
-
- [MonoTODO]
- public override void GenerateKey()
- {
- KeyValue = new byte[KeySizeValue / 8];
- for (int i=0; i < KeyValue.Length; i++) KeyValue[i] = 0;
- }
-}
-
- internal class RC2Transform : SymmetricTransform
- {
- public RC2Transform (RC2 rc2Algo, bool encryption) : base (rc2Algo, encryption, rc2Algo.IV)
- {
- R = new UInt32 [4];
- KeySetup (rc2Algo.Key, rc2Algo.EffectiveKeySize);
- }
-
- private void KeySetup (byte[] key, int t1)
- {
- // Expand key into a byte array, then convert to word
- // array since we always access the key in 16bit chunks.
- byte[] L = new byte [128];
-
- int t = key.Length;
- int t8 = ((t1 + 7) >> 3); // divide by 8
- int tm = 255 % (2 << (8 + t1 - 8*t8 - 1));
-
- Array.Copy (key, 0, L, 0, t);
-
- for (int i=t; i < 128; i++)
- L [i] = (byte) (pitable [(L [i-1] + L [i-t]) & 0xff]);
-
- L [128-t8] = pitable [L [128-t8] & tm];
-
- for (int i=127-t8; i >= 0; i--)
- L [i] = pitable [L [i+1] ^ L [i+t8]];
-
- K = new UInt32 [64];
- int pos = 0;
- for (int i=0; i < 64; i++)
- K [i] = (UInt32) (L [pos++] + L [pos++] * 256);
- }
-
+public sealed class RC2CryptoServiceProvider : RC2 {\r
+ public RC2CryptoServiceProvider() {}\r\r // included to (exactly) match corlib\r public override int EffectiveKeySize {\r get { return base.EffectiveKeySize; }\r set { base.EffectiveKeySize = value; }\r }\r
+ public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)\r {\r Key = rgbKey;\r IV = rgbIV;\r return new RC2Transform (this, false);\r }\r
+ public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)\r {\r Key = rgbKey;\r IV = rgbIV;\r return new RC2Transform (this, true);\r }\r
+ [MonoTODO]\r public override void GenerateIV()\r {\r IVValue = new byte[BlockSizeValue / 8];\r for (int i=0; i < IVValue.Length; i++) IVValue[i] = 0;\r }\r
+ [MonoTODO]\r public override void GenerateKey()\r {\r KeyValue = new byte[KeySizeValue / 8];\r for (int i=0; i < KeyValue.Length; i++) KeyValue[i] = 0;\r }\r}\r
+ internal class RC2Transform : SymmetricTransform\r {\r public RC2Transform (RC2 rc2Algo, bool encryption) : base (rc2Algo, encryption, rc2Algo.IV)\r {\r R = new UInt32 [4];\r KeySetup (rc2Algo.Key, rc2Algo.EffectiveKeySize);\r }\r
+ private void KeySetup (byte[] key, int t1) \r { \r // Expand key into a byte array, then convert to word\r // array since we always access the key in 16bit chunks.\r byte[] L = new byte [128];\r \r int t = key.Length;\r int t8 = ((t1 + 7) >> 3); // divide by 8\r int tm = 255 % (2 << (8 + t1 - 8*t8 - 1));\r \r Array.Copy (key, 0, L, 0, t);\r \r for (int i=t; i < 128; i++) \r L [i] = (byte) (pitable [(L [i-1] + L [i-t]) & 0xff]);\r \r L [128-t8] = pitable [L [128-t8] & tm];\r \r for (int i=127-t8; i >= 0; i--) \r L [i] = pitable [L [i+1] ^ L [i+t8]];\r \r K = new UInt32 [64];\r int pos = 0;\r for (int i=0; i < 64; i++) \r K [i] = (UInt32) (L [pos++] + L [pos++] * 256);\r }\r
protected override void ECB (byte[] input, byte[] output)
{
// unrolled loop, eliminated mul
- R [0] = (UInt32) (input [0] + (input [1] << 8));
- R [1] = (UInt32) (input [2] + (input [3] << 8));
- R [2] = (UInt32) (input [4] + (input [5] << 8));
- R [3] = (UInt32) (input [6] + (input [7] << 8));
-
- if (encrypt) {
- j = 0;
- Mix(); Mix(); Mix(); Mix(); Mix();
- Mash();
- Mix(); Mix(); Mix(); Mix(); Mix(); Mix();
- Mash();
- Mix(); Mix(); Mix(); Mix(); Mix();
- }
- else {
- j = 63;
- RMix(); RMix(); RMix(); RMix(); RMix();
- RMash();
- RMix(); RMix(); RMix(); RMix(); RMix(); RMix();
- RMash();
- RMix(); RMix(); RMix(); RMix(); RMix();
- }
-
- // unrolled loop
- output[0] = (byte) (R [0] & 0xff);
- output[1] = (byte) ((R [0] >> 8) & 0xff);
- output[2] = (byte) (R [1] & 0xff);
- output[3] = (byte) ((R [1] >> 8) & 0xff);
- output[4] = (byte) (R [2] & 0xff);
- output[5] = (byte) ((R [2] >> 8) & 0xff);
- output[6] = (byte) (R [3] & 0xff);
- output[7] = (byte) ((R [3] >> 8) & 0xff);
- }
-
- static public byte[] pitable = {
- 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
- 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
- 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
- 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
- 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
- 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
- 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
- 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
- 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
- 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
- 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
- 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
- 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
- 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
- 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
- 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
- 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
- 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
- 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
- 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
- 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
- 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
- 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
- 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
- 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
- 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
- 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
- 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
- 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
- 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
- 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
- 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad };
-
- // The expanded key (in bottom 16 bits of each word)
- public UInt32[] K;
-
- // The state (again in bottom 16 bits, although we only
- // clear the top 16 bits if needed)
- private UInt32[] R;
-
- // Key indexer
- private int j;
-
- private void Mix()
- {
- R[0] += K[j] + (R[3] & R[2]) + ((~R[3]) & R[1]);
- R[0] = (R[0] << 1) | (R[0]>>15 & 0x1);
-
- R[1] += K[j+1] + (R[0] & R[3]) + ((~R[0]) & R[2]);
- R[1] = (R[1] << 2) | (R[1]>>14 & 0x3);
-
- R[2] += K[j+2] + (R[1] & R[0]) + ((~R[1]) & R[3]);
- R[2] = (R[2] << 3) | (R[2]>>13 & 0x7);
-
- R[3] += K[j+3] + (R[2] & R[1]) + ((~R[2]) & R[0]);
- R[3] = (R[3] << 5) | (R[3]>>11 & 0x1f);
- j += 4;
- }
-
- private void RMix()
- {
- R[3] &= 0xffff;
- R[3] = (R[3] >> 5) | ((R[3] & 0x1f) << 11);
- R[3] -= K[j] + (R[2] & R[1]) + ((~R[2]) & R[0]);
-
- R[2] &= 0xffff;
- R[2] = (R[2] >> 3) | ((R[2] & 0x7) << 13);
- R[2] -= K[j-1] + (R[1] & R[0]) + ((~R[1]) & R[3]);
-
- R[1] &= 0xffff;
- R[1] = (R[1] >> 2) | ((R[1] & 0x3) << 14);
- R[1] -= K[j-2] + (R[0] & R[3]) + ((~R[0]) & R[2]);
-
- R[0] &= 0xffff;
- R[0] = (R[0] >> 1) | ((R[0] & 0x1) << 15);
- R[0] -= K[j-3] + (R[3] & R[2]) + ((~R[3]) & R[1]);
-
- j -= 4;
- }
-
- private void Mash ()
- {
- R [0] += K [R [3] & 63];
- R [1] += K [R [0] & 63];
- R [2] += K [R [1] & 63];
- R [3] += K [R [2] & 63];
- }
-
- private void RMash ()
- {
- R [3] -= K [R [2] & 63];
- R [2] -= K [R [1] & 63];
- R [1] -= K [R [0] & 63];
- R [0] -= K [R [3] & 63];
- }
- }
-}
+ R [0] = (UInt32) (input [0] + (input [1] << 8));\r R [1] = (UInt32) (input [2] + (input [3] << 8));\r R [2] = (UInt32) (input [4] + (input [5] << 8));\r R [3] = (UInt32) (input [6] + (input [7] << 8));\r \r if (encrypt) {\r j = 0;\r Mix(); Mix(); Mix(); Mix(); Mix();\r Mash();\r Mix(); Mix(); Mix(); Mix(); Mix(); Mix();\r Mash();\r Mix(); Mix(); Mix(); Mix(); Mix();\r } \r else {\r j = 63;\r RMix(); RMix(); RMix(); RMix(); RMix();\r RMash();\r RMix(); RMix(); RMix(); RMix(); RMix(); RMix();\r RMash();\r RMix(); RMix(); RMix(); RMix(); RMix();\r }\r\r // unrolled loop
+ output[0] = (byte) (R [0] & 0xff);\r output[1] = (byte) ((R [0] >> 8) & 0xff);\r output[2] = (byte) (R [1] & 0xff);\r output[3] = (byte) ((R [1] >> 8) & 0xff);\r output[4] = (byte) (R [2] & 0xff);\r output[5] = (byte) ((R [2] >> 8) & 0xff);\r output[6] = (byte) (R [3] & 0xff);\r output[7] = (byte) ((R [3] >> 8) & 0xff);\r }\r\r static public byte[] pitable = {\r 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, \r 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,\r 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, \r 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,\r 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, \r 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,\r 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, \r 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,\r 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, \r 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,\r 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, \r 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,\r 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, \r 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,\r 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, \r 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,\r 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, \r 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,\r 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, \r 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,\r 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, \r 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,\r 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, \r 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,\r 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, \r 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,\r 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, \r 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,\r 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, \r 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,\r 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, \r 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad };\r \r // The expanded key (in bottom 16 bits of each word)\r public UInt32[] K;\r \r // The state (again in bottom 16 bits, although we only\r // clear the top 16 bits if needed)\r private UInt32[] R;\r \r // Key indexer\r private int j;\r \r private void Mix() \r {\r R[0] += K[j] + (R[3] & R[2]) + ((~R[3]) & R[1]);\r R[0] = (R[0] << 1) | (R[0]>>15 & 0x1);\r \r R[1] += K[j+1] + (R[0] & R[3]) + ((~R[0]) & R[2]);\r R[1] = (R[1] << 2) | (R[1]>>14 & 0x3);\r \r R[2] += K[j+2] + (R[1] & R[0]) + ((~R[1]) & R[3]);\r R[2] = (R[2] << 3) | (R[2]>>13 & 0x7);\r \r R[3] += K[j+3] + (R[2] & R[1]) + ((~R[2]) & R[0]);\r R[3] = (R[3] << 5) | (R[3]>>11 & 0x1f);\r j += 4;\r }\r \r private void RMix() \r {\r R[3] &= 0xffff;\r R[3] = (R[3] >> 5) | ((R[3] & 0x1f) << 11);\r R[3] -= K[j] + (R[2] & R[1]) + ((~R[2]) & R[0]);\r \r R[2] &= 0xffff;\r R[2] = (R[2] >> 3) | ((R[2] & 0x7) << 13);\r R[2] -= K[j-1] + (R[1] & R[0]) + ((~R[1]) & R[3]);\r\r R[1] &= 0xffff;\r R[1] = (R[1] >> 2) | ((R[1] & 0x3) << 14);\r R[1] -= K[j-2] + (R[0] & R[3]) + ((~R[0]) & R[2]);\r \r R[0] &= 0xffff;\r R[0] = (R[0] >> 1) | ((R[0] & 0x1) << 15);\r R[0] -= K[j-3] + (R[3] & R[2]) + ((~R[3]) & R[1]);\r \r j -= 4;\r }\r
+ private void Mash ()\r {\r R [0] += K [R [3] & 63];\r R [1] += K [R [0] & 63];\r R [2] += K [R [1] & 63];\r R [3] += K [R [2] & 63];\r }\r
+ private void RMash ()\r {\r R [3] -= K [R [2] & 63];\r R [2] -= K [R [1] & 63];\r R [1] -= K [R [0] & 63];\r R [0] -= K [R [3] & 63];\r }\r }\r}\r
\ No newline at end of file
public class RSAOAEPKeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
- protected RSA rsa;
- protected string param;
+ private RSA rsa;
+ private string param;
public RSAOAEPKeyExchangeDeformatter ()
{
public class RSAOAEPKeyExchangeFormatter : AsymmetricKeyExchangeFormatter {
- protected RSA rsa;
- protected RandomNumberGenerator random;
+ private RSA rsa;
+ private RandomNumberGenerator random;
public RSAOAEPKeyExchangeFormatter ()
{
SetKey (key);
}
+ public byte[] Parameter {
+ get { return null; }
+ set { ; }
+ }
+
public override string Parameters {
get { return null; }
}
public class RSAPKCS1KeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter {
- protected RSA rsa;
- protected string param;
- protected RandomNumberGenerator random;
+ private RSA rsa;
+ private string param;
+ private RandomNumberGenerator random;
public RSAPKCS1KeyExchangeDeformatter ()
{
set { param = value; }
}
- public RandomNumberGenerator Rng {
+ public RandomNumberGenerator RNG {
get { return random; }
set { random = value; }
}
if (rsa == null)
throw new CryptographicException ();
byte[] mask = rsa.DecryptValue (rgbData);
+ // it's normal if length = expected length - 1
+ // because the first byte is 0x00 and, as such, is ignored
+ // as a BigInteger
+ // First byte will be 0x02 (because 0x00 was ignored by BigInteger)
+ if (mask[0] != 0x02)
+ return null;
+ // Next will be nonzero random octets(at least 8 bytes)
+ // 0x00 marker
+ int i = 1;
+ for (; i < mask.Length; i++) {
+ if (mask[i] == 0x00)
+ break;
+ }
byte[] secret = null;
- // TODO retreive key from mask
+ // Last bytes will be the secret
+ if (mask[i] == 0x00) {
+ int len = mask.Length - i;
+ secret = new byte [len];
+ Array.Copy (mask, i, secret, 0, len);
+ }
return secret;
}
// which default to SHA1.
public class RSAPKCS1KeyExchangeFormatter: AsymmetricKeyExchangeFormatter
{
- protected RSA rsa;
- protected RandomNumberGenerator random;
+ private RSA rsa;
+ private RandomNumberGenerator random;
public RSAPKCS1KeyExchangeFormatter ()
{
// I2OSP converts a nonnegative integer to an octet string of a specified length.
// in this case xLen is always 4 so we simplify the function
- protected byte[] I2OSP (int x)
+ private byte[] I2OSP (int x)
{
byte[] array = BitConverter.GetBytes (x);
Array.Reverse (array); // big-little endian issues
return array;
}
- [MonoTODO("rsa.EncryptValue throws UnsupportedException on MS framework")]
+ // RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M)
public override byte[] CreateKeyExchange (byte[] rgbData)
{
- int k = rsa.KeySize; // e.g. 128 for 1024 bits keys
+ int k = (rsa.KeySize >> 3); // e.g. 128 for 1024 bits keys
int mLen = rgbData.Length;
// 1. Length checking: If mLen > k \96 11, output \93message too long\94 and stop.
throw new CryptographicException ("message too long");
// 2. EME-PKCS1-v1_5 encoding:
- // a. Generate an octet string PS of length k \96 mLen \96 3 consisting of
- // pseudo-randomly generated nonzero octets. The length of PS will be
- // at least eight octets.
+ // a.Generate an octet string PS of length k \96 mLen \96 3 consisting of
+ // pseudo-randomly generated nonzero octets. The length of PS will be
+ // at least eight octets.
int PSLength = k - mLen - 3;
if (PSLength < 8)
throw new CryptographicException ("PS too short");
random.GetNonZeroBytes (PS);
// b. Concatenate PS, the message M, and other padding to form an encoded
- // message EM of length k octets as
- // EM = 0x00 || 0x02 || PS || 0x00 || M
+ // message EM of length k octets as
+ // EM = 0x00 || 0x02 || PS || 0x00 || M
byte[] EM = new byte [3 + PSLength + mLen];
EM [0] = 0x00;
EM [1] = 0x02;
EM [2 + PSLength] = 0x00;
Array.Copy (rgbData, 0, EM, 3 + PSLength, mLen);
- // 3. RSA encryption:
+ // 3. RSA encryption:
// a. Convert the encoded message EM to an integer message representative
- // m (see Section 4.2):
- // m = OS2IP (EM)
+ // m (see Section 4.2):
+ // m = OS2IP (EM)
byte[] m = EM;
- // b. Apply the RSAEP encryption primitive (Section 5.1.1) to the RSA public
- // key (n, e) and the message representative m to produce an integer
- // ciphertext representative c:
- // c = RSAEP ((n, e), m)
+ // b. Apply the RSAEP encryption primitive (Section 5.1.1) to the RSA public
+ // key (n, e) and the message representative m to produce an integer
+ // ciphertext representative c:
+ // c = RSAEP ((n, e), m)
byte[] c = rsa.EncryptValue (m);
- // c. Convert the ciphertext representative c to a ciphertext C of length k
- // octets (see Section 4.1):
- // C = I2OSP (c, k)
+ // c. Convert the ciphertext representative c to a ciphertext C of length k
+ // octets (see Section 4.1):
+ // C = I2OSP (c, k)
byte[] C = c;
// 4. Output the ciphertext C.
public class RSAPKCS1SignatureDeformatter : AsymmetricSignatureDeformatter {
- protected RSA rsa;
- protected HashAlgorithm hash;
+ private RSA rsa;
+ private HashAlgorithm hash;
public RSAPKCS1SignatureDeformatter ()
{
-//\r
-// System.Security.Cryptography SHA1CryptoServiceProvider Class implementation\r
-//\r
-// Author:\r
-// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)\r
-//\r
-// Copyright 2001 by Matthew S. Ford.\r
-//\r
-\r
-\r
-using System.Security.Cryptography;\r
-\r
-namespace System.Security.Cryptography {\r
-\r
- /// <summary>\r
- /// C# implementation of the SHA1 cryptographic hash function.\r
- /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.\r
- /// </summary>\r
- public sealed class SHA1CryptoServiceProvider : SHA1 {\r
- private const int BLOCK_SIZE_BYTES = 64;\r
- private const int HASH_SIZE_BYTES = 20;\r
- private const int HASH_SIZE_BITS = 160;\r
- [CLSCompliant(false)] private uint[] _H; // these are my chaining variables\r
- [CLSCompliant(false)] private uint count;\r
- private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.\r
- private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.\r
- \r
- /// <summary>\r
- /// Creates a new SHA1CryptoServiceProvider.\r
- /// </summary>\r
- public SHA1CryptoServiceProvider () {\r
- _H = new uint[5];\r
- HashSizeValue = HASH_SIZE_BITS;\r
- _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];\r
- \r
- Initialize();\r
- }\r
-\r
- /// <summary>\r
- /// Drives the hashing function.\r
- /// </summary>\r
- /// <param name="rgb">Byte array containing the data to hash.</param>\r
- /// <param name="start">Where in the input buffer to start.</param>\r
- /// <param name="size">Size in bytes of the data in the buffer to hash.</param>\r
- protected override void HashCore (byte[] rgb, int start, int size) {\r
- int i;\r
- State = 1;\r
-\r
- if (_ProcessingBufferCount != 0) {\r
- if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {\r
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);\r
- _ProcessingBufferCount += size;\r
- return;\r
- }\r
- else {\r
- i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);\r
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);\r
- ProcessBlock (_ProcessingBuffer, 0);\r
- _ProcessingBufferCount = 0;\r
- start += i;\r
- size -= i;\r
- }\r
- }\r
-\r
- for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {\r
- ProcessBlock (rgb, start+i);\r
- }\r
-\r
- if (size%BLOCK_SIZE_BYTES != 0) {\r
- System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);\r
- _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;\r
- }\r
- }\r
- \r
- /// <summary>\r
- /// This finalizes the hash. Takes the data from the chaining variables and returns it.\r
- /// </summary>\r
- protected override byte[] HashFinal () {\r
- byte[] hash = new byte[20];\r
- int i, j;\r
-\r
- ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);\r
-\r
- for (i=0; i<5; i++) {\r
- for (j=0; j<4; j++) {\r
- hash[i*4+j] = (byte)(_H[i] >> (8*(3-j)));\r
- }\r
- }\r
-\r
- State = 0;\r
- return hash;\r
- }\r
-\r
- \r
- /// <summary>\r
- /// Resets the class after use. Called automatically after hashing is done.\r
- /// </summary>\r
- public override void Initialize () {\r
- count = 0;\r
- _ProcessingBufferCount = 0;\r
-\r
- _H[0] = 0x67452301;\r
- _H[1] = 0xefcdab89;\r
- _H[2] = 0x98badcfe;\r
- _H[3] = 0x10325476;\r
- _H[4] = 0xC3D2E1F0;\r
- }\r
-\r
- /// <summary>\r
- /// This is the meat of the hash function. It is what processes each block one at a time.\r
- /// </summary>\r
- /// <param name="inputBuffer">Byte array to process data from.</param>\r
- /// <param name="inputOffset">Where in the byte array to start processing.</param>\r
- private void ProcessBlock(byte[] inputBuffer, int inputOffset) {\r
- uint[] buff = new uint[80];\r
- uint a, b, c, d, e;\r
- int i;\r
-\r
- count += BLOCK_SIZE_BYTES;\r
- \r
- for (i=0; i<16; i++) {\r
- buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)\r
- | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)\r
- | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)\r
- | ((uint)(inputBuffer[inputOffset+4*i+3]));\r
- }\r
-\r
- for (i=16; i<80; i++) {\r
- buff[i] = ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) << 1)\r
- | ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) >> 31);\r
- }\r
- \r
- a = _H[0];\r
- b = _H[1];\r
- c = _H[2];\r
- d = _H[3];\r
- e = _H[4];\r
-\r
-\r
- // This function was unrolled because it seems to be doubling our performance with current compiler/VM.\r
- // Possibly roll up if this changes.\r
- \r
- // ---- Round 1 --------\r
- \r
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[0];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[1];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[2];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[3];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[4];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[5];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[6];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[7];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[8];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[9];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[10];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[11];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[12];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[13];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[14];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[15];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[16];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[17];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[18];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[19];\r
- c = (c << 30) | (c >> 2);\r
-\r
-\r
-\r
- // ---- Round 2 --------\r
- \r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[20];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[21];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[22];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[23];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[24];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[25];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[26];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[27];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[28];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[29];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[30];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[31];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[32];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[33];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[34];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[35];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[36];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[37];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[38];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[39];\r
- c = (c << 30) | (c >> 2);\r
-\r
-\r
-\r
- // ---- Round 3 --------\r
- \r
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[40];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[41];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[42];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[43];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[44];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[45];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[46];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[47];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[48];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[49];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[50];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[51];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[52];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[53];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[54];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[55];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[56];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[57];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[58];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[59];\r
- c = (c << 30) | (c >> 2);\r
-\r
-\r
-\r
- // ---- Round 4 --------\r
- \r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[60];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[61];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[62];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[63];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[64];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[65];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[66];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[67];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[68];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[69];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[70];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[71];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[72];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[73];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[74];\r
- c = (c << 30) | (c >> 2);\r
-\r
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[75];\r
- b = (b << 30) | (b >> 2);\r
-\r
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[76];\r
- a = (a << 30) | (a >> 2);\r
-\r
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[77];\r
- e = (e << 30) | (e >> 2);\r
-\r
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[78];\r
- d = (d << 30) | (d >> 2);\r
-\r
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[79];\r
- c = (c << 30) | (c >> 2);\r
-\r
-\r
- _H[0] += a;\r
- _H[1] += b;\r
- _H[2] += c;\r
- _H[3] += d;\r
- _H[4] += e;\r
- }\r
- \r
- /// <summary>\r
- /// Pads and then processes the final block.\r
- /// Non-standard.\r
- /// </summary>\r
- /// <param name="inputBuffer">Buffer to grab data from.</param>\r
- /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>\r
- /// <param name="inputCount">How much data in bytes in the buffer to use.</param>\r
- private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {\r
- byte[] fooBuffer;\r
- int paddingSize;\r
- int i;\r
- uint size;\r
-\r
- paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);\r
-\r
- if (paddingSize < 1)\r
- paddingSize += BLOCK_SIZE_BYTES;\r
-\r
- fooBuffer = new byte[inputCount+paddingSize+8];\r
-\r
- for (i=0; i<inputCount; i++) {\r
- fooBuffer[i] = inputBuffer[i+inputOffset];\r
- }\r
-\r
- fooBuffer[inputCount] = 0x80;\r
- for (i=inputCount+1; i<inputCount+paddingSize; i++) {\r
- fooBuffer[i] = 0x00;\r
- }\r
-\r
- size = (uint)(count+inputCount);\r
- size *= 8; // I deal in bytes. They algorythm deals in bits.\r
-\r
- fooBuffer[inputCount+paddingSize] = 0x00;\r
- fooBuffer[inputCount+paddingSize+1] = 0x00;\r
- fooBuffer[inputCount+paddingSize+2] = 0x00;\r
- fooBuffer[inputCount+paddingSize+3] = 0x00;\r
-\r
- fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);\r
- fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);\r
- fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);\r
- fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);\r
-\r
- ProcessBlock(fooBuffer, 0);\r
-\r
- if (inputCount+paddingSize+8 == 128) {\r
- ProcessBlock(fooBuffer, 64);\r
- }\r
- }\r
- }\r
-}\r
-\r
+//
+// System.Security.Cryptography SHA1CryptoServiceProvider Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+// Sebastien Pouliot (spouliot@motus.com)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+// Note:
+// The MS Framework includes two (almost) identical class for SHA1.
+// SHA1Managed is a 100% managed implementation.
+// SHA1CryptoServiceProvider (this file) is a wrapper on CryptoAPI.
+// Mono must provide those two class for binayry compatibility.
+// In our case both class are wrappers around a managed internal class SHA1Internal.
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// C# implementation of the SHA1 cryptographic hash function.
+ /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.
+ /// </summary>
+ internal class SHA1Internal {
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 20;
+ private const int HASH_SIZE_BITS = 160;
+ [CLSCompliant(false)] private uint[] _H; // these are my chaining variables
+ [CLSCompliant(false)] private uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new SHA1CryptoServiceProvider.
+ /// </summary>
+ public SHA1Internal ()
+ {
+ _H = new uint[5];
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ Initialize();
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ public void HashCore (byte[] rgb, int start, int size)
+ {
+ int i;
+
+ if (_ProcessingBufferCount != 0) {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0) {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ public byte[] HashFinal ()
+ {
+ byte[] hash = new byte[20];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<5; i++) {
+ for (j=0; j<4; j++) {
+ hash[i*4+j] = (byte)(_H[i] >> (8*(3-j)));
+ }
+ }
+
+ return hash;
+ }
+
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public void Initialize ()
+ {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x67452301;
+ _H[1] = 0xefcdab89;
+ _H[2] = 0x98badcfe;
+ _H[3] = 0x10325476;
+ _H[4] = 0xC3D2E1F0;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ public void ProcessBlock(byte[] inputBuffer, int inputOffset)
+ {
+ uint[] buff = new uint[80];
+ uint a, b, c, d, e;
+ int i;
+
+ count += BLOCK_SIZE_BYTES;
+
+ for (i=0; i<16; i++) {
+ buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
+ | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
+ | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
+ | ((uint)(inputBuffer[inputOffset+4*i+3]));
+ }
+
+ for (i=16; i<80; i++) {
+ buff[i] = ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) << 1)
+ | ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) >> 31);
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+ e = _H[4];
+
+
+ // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
+ // Possibly roll up if this changes.
+
+ // ---- Round 1 --------
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[0];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[1];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[2];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[3];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[4];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[5];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[6];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[7];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[8];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[9];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[10];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[11];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[12];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[13];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[14];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[15];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[16];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[17];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[18];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[19];
+ c = (c << 30) | (c >> 2);
+
+
+
+ // ---- Round 2 --------
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[20];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[21];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[22];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[23];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[24];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[25];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[26];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[27];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[28];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[29];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[30];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[31];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[32];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[33];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[34];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[35];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[36];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[37];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[38];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[39];
+ c = (c << 30) | (c >> 2);
+
+
+
+ // ---- Round 3 --------
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[40];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[41];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[42];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[43];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[44];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[45];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[46];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[47];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[48];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[49];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[50];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[51];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[52];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[53];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[54];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[55];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[56];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[57];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[58];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[59];
+ c = (c << 30) | (c >> 2);
+
+
+
+ // ---- Round 4 --------
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[60];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[61];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[62];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[63];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[64];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[65];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[66];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[67];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[68];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[69];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[70];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[71];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[72];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[73];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[74];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[75];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[76];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[77];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[78];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[79];
+ c = (c << 30) | (c >> 2);
+
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ _H[4] += e;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// Non-standard.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ public void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++) {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8; // I deal in bytes. They algorythm deals in bits.
+
+ fooBuffer[inputCount+paddingSize] = 0x00;
+ fooBuffer[inputCount+paddingSize+1] = 0x00;
+ fooBuffer[inputCount+paddingSize+2] = 0x00;
+ fooBuffer[inputCount+paddingSize+3] = 0x00;
+
+ fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);
+ fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128) {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+ }
+
+ public sealed class SHA1CryptoServiceProvider : SHA1 {
+
+ private SHA1Internal sha;
+
+ public SHA1CryptoServiceProvider ()
+ {
+ sha = new SHA1Internal ();
+ }
+
+ ~SHA1CryptoServiceProvider ()
+ {
+ Dispose (false);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ // nothing new to do (managed implementation)
+ base.Dispose (disposing);
+ }
+
+ protected override void HashCore (byte[] rgb, int start, int size)
+ {
+ State = 1;
+ sha.HashCore (rgb, start, size);
+ }
+
+ protected override byte[] HashFinal ()
+ {
+ State = 0;
+ return sha.HashFinal ();
+ }
+
+ public override void Initialize ()
+ {
+ sha.Initialize ();
+ }
+
+ private void ProcessBlock (byte[] inputBuffer, int inputOffset)
+ {
+ sha.ProcessBlock (inputBuffer, inputOffset);
+ }
+
+ private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ sha.ProcessFinalBlock (inputBuffer, inputOffset, inputCount);
+ }
+ }
+
+}
+
--- /dev/null
+//
+// System.Security.Cryptography SHA1Managed Class implementation
+//
+// Author:
+// Sebastien Pouliot (spouliot@motus.com)
+//
+// (C) 2002 Motus Technologies Inc. (http://www.motus.com)
+//
+
+namespace System.Security.Cryptography {
+
+// Note:
+// The MS Framework includes two (almost) identical class for SHA1.
+// SHA1Managed (this file) is a 100% managed implementation.
+// SHA1CryptoServiceProvider is a wrapper on CryptoAPI.
+// Mono must provide those two class for binayry compatibility.
+// In our case both class are wrappers around a managed internal class SHA1Internal.
+
+public sealed class SHA1Managed : SHA1 {
+
+ private SHA1Internal sha;
+
+ public SHA1Managed ()
+ {
+ sha = new SHA1Internal ();
+ }
+
+ ~SHA1Managed ()
+ {
+ Dispose (false);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ // nothing new to do (managed implementation)
+ base.Dispose (disposing);
+ }
+
+ protected override void HashCore (byte[] rgb, int start, int size)
+ {
+ State = 1;
+ sha.HashCore (rgb, start, size);
+ }
+
+ protected override byte[] HashFinal ()
+ {
+ State = 0;
+ return sha.HashFinal ();
+ }
+
+ public override void Initialize ()
+ {
+ sha.Initialize ();
+ }
+
+ private void ProcessBlock (byte[] inputBuffer, int inputOffset)
+ {
+ sha.ProcessBlock (inputBuffer, inputOffset);
+ }
+
+ private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ sha.ProcessFinalBlock (inputBuffer, inputOffset, inputCount);
+ }
+}
+
+}
+
-//\r
-// System.Security.Cryptography SHA256Managed Class implementation\r
-//\r
-// Author:\r
-// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)\r
-//\r
-// (C) 2001 \r
-//\r
-\r
-\r
-using System.Security.Cryptography;\r
-\r
-namespace System.Security.Cryptography {\r
- \r
- /// <summary>\r
- /// C# implementation of the SHA1 cryptographic hash function.\r
- /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.\r
- /// </summary>\r
- public class SHA256Managed : SHA256 {\r
- private const int BLOCK_SIZE_BYTES = 64;\r
- private const int HASH_SIZE_BYTES = 32;\r
- private const int HASH_SIZE_BITS = 256;\r
- [CLSCompliant(false)] protected uint[] _H;\r
- [CLSCompliant(false)] private uint[] K;\r
- [CLSCompliant(false)] protected uint count;\r
- private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.\r
- private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.\r
- \r
- /// <summary>\r
- /// Creates a new SHA256Managed class.\r
- /// </summary>\r
- public SHA256Managed () {\r
- _H = new uint[8];\r
- HashSizeValue = HASH_SIZE_BITS;\r
- _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];\r
-\r
- K = new uint[64];\r
- K[0] = 0x428A2F98; K[1] = 0x71374491; K[2] = 0xB5C0FBCF; K[3] = 0xE9B5DBA5;\r
- K[4] = 0x3956C25B; K[5] = 0x59F111F1; K[6] = 0x923F82A4; K[7] = 0xAB1C5ED5;\r
- K[8] = 0xD807AA98; K[9] = 0x12835B01; K[10] = 0x243185BE; K[11] = 0x550C7DC3;\r
- K[12] = 0x72BE5D74; K[13] = 0x80DEB1FE; K[14] = 0x9BDC06A7; K[15] = 0xC19BF174;\r
- K[16] = 0xE49B69C1; K[17] = 0xEFBE4786; K[18] = 0x0FC19DC6; K[19] = 0x240CA1CC;\r
- K[20] = 0x2DE92C6F; K[21] = 0x4A7484AA; K[22] = 0x5CB0A9DC; K[23] = 0x76F988DA;\r
- K[24] = 0x983E5152; K[25] = 0xA831C66D; K[26] = 0xB00327C8; K[27] = 0xBF597FC7;\r
- K[28] = 0xC6E00BF3; K[29] = 0xD5A79147; K[30] = 0x06CA6351; K[31] = 0x14292967;\r
- K[32] = 0x27B70A85; K[33] = 0x2E1B2138; K[34] = 0x4D2C6DFC; K[35] = 0x53380D13;\r
- K[36] = 0x650A7354; K[37] = 0x766A0ABB; K[38] = 0x81C2C92E; K[39] = 0x92722C85;\r
- K[40] = 0xA2BFE8A1; K[41] = 0xA81A664B; K[42] = 0xC24B8B70; K[43] = 0xC76C51A3;\r
- K[44] = 0xD192E819; K[45] = 0xD6990624; K[46] = 0xF40E3585; K[47] = 0x106AA070;\r
- K[48] = 0x19A4C116; K[49] = 0x1E376C08; K[50] = 0x2748774C; K[51] = 0x34B0BCB5;\r
- K[52] = 0x391C0CB3; K[53] = 0x4ED8AA4A; K[54] = 0x5B9CCA4F; K[55] = 0x682E6FF3;\r
- K[56] = 0x748F82EE; K[57] = 0x78A5636F; K[58] = 0x84C87814; K[59] = 0x8CC70208;\r
- K[60] = 0x90BEFFFA; K[61] = 0xA4506CEB; K[62] = 0xBEF9A3F7; K[63] = 0xC67178F2;\r
- \r
- Initialize();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Internal function handling a subset of the algorithm.\r
- /// </summary>\r
- private uint Ch (uint u, uint v, uint w) {\r
- return (u&v) ^ (~u&w);\r
- }\r
-\r
- /// <summary>\r
- /// Internal function handling a subset of the algorithm.\r
- /// </summary>\r
- private uint Maj (uint u, uint v, uint w) {\r
- return (u&v) ^ (u&w) ^ (v&w);\r
- }\r
-\r
- /// <summary>\r
- /// Internal function handling a subset of the algorithm.\r
- /// </summary>\r
- private uint Ro0 (uint x) {\r
- return ((x >> 7) | (x << 25))\r
- ^ ((x >> 18) | (x << 14))\r
- ^ (x >> 3);\r
- }\r
-\r
- /// <summary>\r
- /// Internal function handling a subset of the algorithm.\r
- /// </summary>\r
- private uint Ro1 (uint x) {\r
- return ((x >> 17) | (x << 15))\r
- ^ ((x >> 19) | (x << 13))\r
- ^ (x >> 10);\r
- }\r
-\r
- /// <summary>\r
- /// Internal function handling a subset of the algorithm.\r
- /// </summary>\r
- private uint Sig0 (uint x) {\r
- return ((x >> 2) | (x << 30))\r
- ^ ((x >> 13) | (x << 19))\r
- ^ ((x >> 22) | (x << 10));\r
- }\r
-\r
- /// <summary>\r
- /// Internal function handling a subset of the algorithm.\r
- /// </summary>\r
- private uint Sig1 (uint x) {\r
- return ((x >> 6) | (x << 26))\r
- ^ ((x >> 11) | (x << 21))\r
- ^ ((x >> 25) | (x << 7));\r
- }\r
-\r
- /// <summary>\r
- /// Drives the hashing function.\r
- /// </summary>\r
- /// <param name="rgb">Byte array containing the data to hash.</param>\r
- /// <param name="start">Where in the input buffer to start.</param>\r
- /// <param name="size">Size in bytes of the data in the buffer to hash.</param>\r
- protected override void HashCore (byte[] rgb, int start, int size) {\r
- int i;\r
- State = 1;\r
-\r
- if (_ProcessingBufferCount != 0) {\r
- if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {\r
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);\r
- _ProcessingBufferCount += size;\r
- return;\r
- }\r
- else {\r
- i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);\r
- System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);\r
- ProcessBlock (_ProcessingBuffer, 0);\r
- _ProcessingBufferCount = 0;\r
- start += i;\r
- size -= i;\r
- }\r
- }\r
-\r
- for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {\r
- ProcessBlock (rgb, start+i);\r
- }\r
-\r
- if (size%BLOCK_SIZE_BYTES != 0) {\r
- System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);\r
- _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;\r
- }\r
- }\r
- \r
- /// <summary>\r
- /// This finalizes the hash. Takes the data from the chaining variables and returns it.\r
- /// </summary>\r
- protected override byte[] HashFinal () {\r
- byte[] hash = new byte[32];\r
- int i, j;\r
-\r
- ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);\r
-\r
- for (i=0; i<8; i++) {\r
- for (j=0; j<4; j++) {\r
- hash[i*4+j] = (byte)(_H[i] >> (24-j*8));\r
- }\r
- }\r
-\r
- State = 0;\r
- return hash;\r
- }\r
-\r
- /// <summary>\r
- /// Resets the class after use. Called automatically after hashing is done.\r
- /// </summary>\r
- public override void Initialize () {\r
- count = 0;\r
- _ProcessingBufferCount = 0;\r
- \r
- _H[0] = 0x6A09E667;\r
- _H[1] = 0xBB67AE85;\r
- _H[2] = 0x3C6EF372;\r
- _H[3] = 0xA54FF53A;\r
- _H[4] = 0x510E527F;\r
- _H[5] = 0x9B05688C;\r
- _H[6] = 0x1F83D9AB;\r
- _H[7] = 0x5BE0CD19;\r
- }\r
-\r
- /// <summary>\r
- /// This is the meat of the hash function. It is what processes each block one at a time.\r
- /// </summary>\r
- /// <param name="inputBuffer">Byte array to process data from.</param>\r
- /// <param name="inputOffset">Where in the byte array to start processing.</param>\r
- public void ProcessBlock(byte[] inputBuffer, int inputOffset) {\r
- uint a, b, c, d, e, f, g, h;\r
- uint t1, t2;\r
- int i;\r
- uint[] buff;\r
- \r
- count += BLOCK_SIZE_BYTES;\r
- \r
- buff = new uint[64];\r
-\r
- for (i=0; i<16; i++) {\r
- buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)\r
- | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)\r
- | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)\r
- | ((uint)(inputBuffer[inputOffset+4*i+3]));\r
- }\r
-\r
- \r
- for (i=16; i<64; i++) {\r
- buff[i] = Ro1(buff[i-2]) + buff[i-7] + Ro0(buff[i-15]) + buff[i-16];\r
- }\r
-\r
- a = _H[0];\r
- b = _H[1];\r
- c = _H[2];\r
- d = _H[3];\r
- e = _H[4];\r
- f = _H[5];\r
- g = _H[6];\r
- h = _H[7];\r
-\r
- for (i=0; i<64; i++) {\r
- t1 = h + Sig1(e) + Ch(e,f,g) + K[i] + buff[i];\r
- t2 = Sig0(a) + Maj(a,b,c);\r
- h = g;\r
- g = f;\r
- f = e;\r
- e = d + t1;\r
- d = c;\r
- c = b;\r
- b = a;\r
- a = t1 + t2;\r
- }\r
-\r
- _H[0] += a;\r
- _H[1] += b;\r
- _H[2] += c;\r
- _H[3] += d;\r
- _H[4] += e;\r
- _H[5] += f;\r
- _H[6] += g;\r
- _H[7] += h;\r
- }\r
- \r
- /// <summary>\r
- /// Pads and then processes the final block.\r
- /// Non-standard.\r
- /// </summary>\r
- /// <param name="inputBuffer">Buffer to grab data from.</param>\r
- /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>\r
- /// <param name="inputCount">How much data in bytes in the buffer to use.</param>\r
- public void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {\r
- byte[] fooBuffer;\r
- int paddingSize;\r
- int i;\r
- uint size;\r
-\r
- paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);\r
-\r
- if (paddingSize < 1)\r
- paddingSize += BLOCK_SIZE_BYTES;\r
-\r
- fooBuffer = new byte[inputCount+paddingSize+8];\r
-\r
- for (i=0; i<inputCount; i++) {\r
- fooBuffer[i] = inputBuffer[i+inputOffset];\r
- }\r
-\r
- fooBuffer[inputCount] = 0x80;\r
- for (i=inputCount+1; i<inputCount+paddingSize; i++) {\r
- fooBuffer[i] = 0x00;\r
- }\r
-\r
- size = (uint)(count+inputCount);\r
- size *= 8;\r
-\r
- fooBuffer[inputCount+paddingSize] = 0x00;\r
- fooBuffer[inputCount+paddingSize+1] = 0x00;\r
- fooBuffer[inputCount+paddingSize+2] = 0x00;\r
- fooBuffer[inputCount+paddingSize+3] = 0x00;\r
-\r
- fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);\r
- fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);\r
- fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);\r
- fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);\r
-\r
- ProcessBlock(fooBuffer, 0);\r
-\r
- if (inputCount+paddingSize+8 == 128) {\r
- ProcessBlock(fooBuffer, 64);\r
- }\r
- }\r
- }\r
-}\r
-\r
+//
+// System.Security.Cryptography SHA256Managed Class implementation
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// (C) 2001
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// C# implementation of the SHA1 cryptographic hash function.
+ /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.
+ /// </summary>
+ public class SHA256Managed : SHA256 {
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 32;
+ private const int HASH_SIZE_BITS = 256;
+ [CLSCompliant(false)] private uint[] _H;
+ [CLSCompliant(false)] private uint[] K;
+ [CLSCompliant(false)] private uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new SHA256Managed class.
+ /// </summary>
+ public SHA256Managed ()
+ {
+ _H = new uint[8];
+ HashSizeValue = HASH_SIZE_BITS;
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ K = new uint[64];
+ K[0] = 0x428A2F98; K[1] = 0x71374491; K[2] = 0xB5C0FBCF; K[3] = 0xE9B5DBA5;
+ K[4] = 0x3956C25B; K[5] = 0x59F111F1; K[6] = 0x923F82A4; K[7] = 0xAB1C5ED5;
+ K[8] = 0xD807AA98; K[9] = 0x12835B01; K[10] = 0x243185BE; K[11] = 0x550C7DC3;
+ K[12] = 0x72BE5D74; K[13] = 0x80DEB1FE; K[14] = 0x9BDC06A7; K[15] = 0xC19BF174;
+ K[16] = 0xE49B69C1; K[17] = 0xEFBE4786; K[18] = 0x0FC19DC6; K[19] = 0x240CA1CC;
+ K[20] = 0x2DE92C6F; K[21] = 0x4A7484AA; K[22] = 0x5CB0A9DC; K[23] = 0x76F988DA;
+ K[24] = 0x983E5152; K[25] = 0xA831C66D; K[26] = 0xB00327C8; K[27] = 0xBF597FC7;
+ K[28] = 0xC6E00BF3; K[29] = 0xD5A79147; K[30] = 0x06CA6351; K[31] = 0x14292967;
+ K[32] = 0x27B70A85; K[33] = 0x2E1B2138; K[34] = 0x4D2C6DFC; K[35] = 0x53380D13;
+ K[36] = 0x650A7354; K[37] = 0x766A0ABB; K[38] = 0x81C2C92E; K[39] = 0x92722C85;
+ K[40] = 0xA2BFE8A1; K[41] = 0xA81A664B; K[42] = 0xC24B8B70; K[43] = 0xC76C51A3;
+ K[44] = 0xD192E819; K[45] = 0xD6990624; K[46] = 0xF40E3585; K[47] = 0x106AA070;
+ K[48] = 0x19A4C116; K[49] = 0x1E376C08; K[50] = 0x2748774C; K[51] = 0x34B0BCB5;
+ K[52] = 0x391C0CB3; K[53] = 0x4ED8AA4A; K[54] = 0x5B9CCA4F; K[55] = 0x682E6FF3;
+ K[56] = 0x748F82EE; K[57] = 0x78A5636F; K[58] = 0x84C87814; K[59] = 0x8CC70208;
+ K[60] = 0x90BEFFFA; K[61] = 0xA4506CEB; K[62] = 0xBEF9A3F7; K[63] = 0xC67178F2;
+
+ Initialize();
+ }
+
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Ch (uint u, uint v, uint w)
+ {
+ return (u&v) ^ (~u&w);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Maj (uint u, uint v, uint w)
+ {
+ return (u&v) ^ (u&w) ^ (v&w);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Ro0 (uint x)
+ {
+ return ((x >> 7) | (x << 25))
+ ^ ((x >> 18) | (x << 14))
+ ^ (x >> 3);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Ro1 (uint x)
+ {
+ return ((x >> 17) | (x << 15))
+ ^ ((x >> 19) | (x << 13))
+ ^ (x >> 10);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Sig0 (uint x)
+ {
+ return ((x >> 2) | (x << 30))
+ ^ ((x >> 13) | (x << 19))
+ ^ ((x >> 22) | (x << 10));
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Sig1 (uint x)
+ {
+ return ((x >> 6) | (x << 26))
+ ^ ((x >> 11) | (x << 21))
+ ^ ((x >> 25) | (x << 7));
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ protected override void HashCore (byte[] rgb, int start, int size)
+ {
+ int i;
+ State = 1;
+
+ if (_ProcessingBufferCount != 0) {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0) {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ protected override byte[] HashFinal ()
+ {
+ byte[] hash = new byte[32];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<8; i++) {
+ for (j=0; j<4; j++) {
+ hash[i*4+j] = (byte)(_H[i] >> (24-j*8));
+ }
+ }
+
+ State = 0;
+ return hash;
+ }
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public override void Initialize ()
+ {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x6A09E667;
+ _H[1] = 0xBB67AE85;
+ _H[2] = 0x3C6EF372;
+ _H[3] = 0xA54FF53A;
+ _H[4] = 0x510E527F;
+ _H[5] = 0x9B05688C;
+ _H[6] = 0x1F83D9AB;
+ _H[7] = 0x5BE0CD19;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ private void ProcessBlock (byte[] inputBuffer, int inputOffset)
+ {
+ uint a, b, c, d, e, f, g, h;
+ uint t1, t2;
+ int i;
+ uint[] buff;
+
+ count += BLOCK_SIZE_BYTES;
+
+ buff = new uint[64];
+
+ for (i=0; i<16; i++) {
+ buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
+ | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
+ | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
+ | ((uint)(inputBuffer[inputOffset+4*i+3]));
+ }
+
+
+ for (i=16; i<64; i++) {
+ buff[i] = Ro1(buff[i-2]) + buff[i-7] + Ro0(buff[i-15]) + buff[i-16];
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+ e = _H[4];
+ f = _H[5];
+ g = _H[6];
+ h = _H[7];
+
+ for (i=0; i<64; i++) {
+ t1 = h + Sig1(e) + Ch(e,f,g) + K[i] + buff[i];
+ t2 = Sig0(a) + Maj(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ _H[4] += e;
+ _H[5] += f;
+ _H[6] += g;
+ _H[7] += h;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// Non-standard.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++) {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8;
+
+ fooBuffer[inputCount+paddingSize] = 0x00;
+ fooBuffer[inputCount+paddingSize+1] = 0x00;
+ fooBuffer[inputCount+paddingSize+2] = 0x00;
+ fooBuffer[inputCount+paddingSize+3] = 0x00;
+
+ fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);
+ fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128) {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+ }
+}
+
private ulong byteCount2;
[CLSCompliant(false)]
- protected ulong H1, H2, H3, H4, H5, H6, H7, H8;
-
+ private ulong H1, H2, H3, H4, H5, H6, H7, H8;
[CLSCompliant(false)]
private ulong[] W = new ulong [80];
private int wOff;
0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL,
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L
};
-
}
}
private byte[] xBuf;
private int xBufOff;
- [CLSCompliant(false)]
private ulong byteCount1;
- [CLSCompliant(false)]
private ulong byteCount2;
- [CLSCompliant(false)]
- protected ulong H1, H2, H3, H4, H5, H6, H7, H8;
+ private ulong H1, H2, H3, H4, H5, H6, H7, H8;
- [CLSCompliant(false)]
private ulong[] W = new ulong [80];
private int wOff;
// This class implement most of the common code required for symmetric
// algorithm transforms, like:
- // - CipherMode: Build CBC... on top of (descendant supplied) ECB
+ // - CipherMode: Builds CBC and CFB on top of (descendant supplied) ECB
// - PaddingMode, transform properties, multiple blocks, reuse...
//
// Descendants MUST:
Dispose (false);
}
- public void Dispose ()
+ void IDisposable.Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this); // Finalization is now unnecessary
Dispose (false);
}
- public void Dispose ()
+ public void Clear()
+ {
+ Dispose (true);
+ }
+
+ void IDisposable.Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this); // Finalization is now unnecessary
}
- protected void Dispose (bool disposing)
+ protected virtual void Dispose (bool disposing)
{
if (!m_disposed) {
// always zeroize keys
Dispose (true);
}
- public void Dispose ()
+ void IDisposable.Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this); // Finalization is now unnecessary
// not free :-(
// http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E52%2D1998
-public class TripleDESCryptoServiceProvider : TripleDES {
+public sealed class TripleDESCryptoServiceProvider : TripleDES {
public TripleDESCryptoServiceProvider ()
{