Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2017
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.48 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using System.Security.Cryptography;
  5.  
  6. public class MD4 : HashAlgorithm
  7. {
  8.     private uint _a;
  9.     private uint _b;
  10.     private uint _c;
  11.     private uint _d;
  12.     private uint[] _x;
  13.     private int _bytesProcessed;
  14.  
  15.     public MD4()
  16.     {
  17.         _x = new uint[16];
  18.  
  19.         Initialize();
  20.     }
  21.  
  22.     public override void Initialize()
  23.     {
  24.         _a = 0x67452301;
  25.         _b = 0xefcdab89;
  26.         _c = 0x98badcfe;
  27.         _d = 0x10325476;
  28.  
  29.         _bytesProcessed = 0;
  30.     }
  31.  
  32.     protected override void HashCore(byte[] array, int offset, int length)
  33.     {
  34.         ProcessMessage(Bytes(array, offset, length));
  35.     }
  36.  
  37.     protected override byte[] HashFinal()
  38.     {
  39.         try
  40.         {
  41.             ProcessMessage(Padding());
  42.             var resoult = new[] { _a, _b, _c, _d }
  43.                 .SelectMany(Bytes).ToArray();
  44.             return resoult;
  45.         }
  46.         finally
  47.         {
  48.             Initialize();
  49.         }
  50.     }
  51.  
  52.     private void ProcessMessage(IEnumerable<byte> bytes)
  53.     {
  54.         foreach (byte b in bytes)
  55.         {
  56.             int c = _bytesProcessed & 63;
  57.             int i = c >> 2;
  58.             int s = (c & 3) << 3;
  59.  
  60.             _x[i] = (_x[i] & ~((uint)255 << s)) | ((uint)b << s);
  61.  
  62.             if (c == 63)
  63.             {
  64.                 Process16WordBlock();
  65.             }
  66.  
  67.             _bytesProcessed++;
  68.         }
  69.     }
  70.  
  71.     private static IEnumerable<byte> Bytes(byte[] bytes, int offset, int length)
  72.     {
  73.         for (int i = offset; i < length; i++)
  74.         {
  75.             yield return bytes[i];
  76.         }
  77.     }
  78.  
  79.     private IEnumerable<byte> Bytes(uint word)
  80.     {
  81.         return new List<byte>()
  82.         {
  83.             (byte)(word & 255),
  84.             (byte)((word >> 8) & 255),
  85.             (byte)((word >> 16) & 255),
  86.             (byte)((word >> 24) & 255)
  87.         };
  88.     }
  89.  
  90.     private IEnumerable<byte> Repeat(byte value, int count)
  91.     {
  92.         var resoult = new List<byte>();
  93.         for (int i = 0; i < count; i++)
  94.         {
  95.             resoult.Add(value);
  96.         }
  97.         return resoult;
  98.     }
  99.  
  100.     private IEnumerable<byte> Padding()
  101.     {
  102.         var resoult = Repeat(128, 1).Concat(Repeat(0, ((_bytesProcessed + 8) & 0x7fffffc0) + 55 - _bytesProcessed));
  103.         var res1 = resoult.Concat(Bytes((uint)_bytesProcessed << 3));
  104.         var res2 = res1.Concat(Repeat(0, 4)).ToList();
  105.         return res2;
  106.     }
  107.  
  108.     private void Process16WordBlock()
  109.     {
  110.         uint aa = _a;
  111.         uint bb = _b;
  112.         uint cc = _c;
  113.         uint dd = _d;
  114.  
  115.         foreach (int k in new[] { 0, 4, 8, 12 })
  116.         {
  117.             aa = Round1Operation(aa, bb, cc, dd, _x[k], 3);
  118.             dd = Round1Operation(dd, aa, bb, cc, _x[k + 1], 7);
  119.             cc = Round1Operation(cc, dd, aa, bb, _x[k + 2], 11);
  120.             bb = Round1Operation(bb, cc, dd, aa, _x[k + 3], 19);
  121.         }
  122.  
  123.         foreach (int k in new[] { 0, 1, 2, 3 })
  124.         {
  125.             aa = Round2Operation(aa, bb, cc, dd, _x[k], 3);
  126.             dd = Round2Operation(dd, aa, bb, cc, _x[k + 4], 5);
  127.             cc = Round2Operation(cc, dd, aa, bb, _x[k + 8], 9);
  128.             bb = Round2Operation(bb, cc, dd, aa, _x[k + 12], 13);
  129.         }
  130.  
  131.         foreach (int k in new[] { 0, 2, 1, 3 })
  132.         {
  133.             aa = Round3Operation(aa, bb, cc, dd, _x[k], 3);
  134.             dd = Round3Operation(dd, aa, bb, cc, _x[k + 8], 9);
  135.             cc = Round3Operation(cc, dd, aa, bb, _x[k + 4], 11);
  136.             bb = Round3Operation(bb, cc, dd, aa, _x[k + 12], 15);
  137.         }
  138.  
  139.         unchecked
  140.         {
  141.             _a += aa;
  142.             _b += bb;
  143.             _c += cc;
  144.             _d += dd;
  145.         }
  146.     }
  147.  
  148.     private static uint ROL(uint value, int numberOfBits)
  149.     {
  150.         return (value << numberOfBits) | (value >> (32 - numberOfBits));
  151.     }
  152.  
  153.     private static uint Round1Operation(uint a, uint b, uint c, uint d, uint xk, int s)
  154.     {
  155.         unchecked
  156.         {
  157.             return ROL(a + ((b & c) | (~b & d)) + xk, s);
  158.         }
  159.     }
  160.  
  161.     private static uint Round2Operation(uint a, uint b, uint c, uint d, uint xk, int s)
  162.     {
  163.         unchecked
  164.         {
  165.             return ROL(a + ((b & c) | (b & d) | (c & d)) + xk + 0x5a827999, s);
  166.         }
  167.     }
  168.  
  169.     private static uint Round3Operation(uint a, uint b, uint c, uint d, uint xk, int s)
  170.     {
  171.         unchecked
  172.         {
  173.             return ROL(a + (b ^ c ^ d) + xk + 0x6ed9eba1, s);
  174.         }
  175.     }
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement