protected override byte[] HashFinal() { // save old hash if buffer is partially filled var oldHash = new uint[NumHashValues]; Array.Copy(m_hash, oldHash, m_hash.Length); // process remaining bytes ProcessBuffer(); var hash = new byte[HashBytes]; for (int i = 0; i < NumHashValues; i++) { BitConverterEndian.SetBytesBE(m_hash[i], hash, i * sizeof(uint)); } // Restore the old hash. Array.Copy(oldHash, m_hash, oldHash.Length); return(hash); }
private void ProcessBlock(byte[] block, int startIndex) { // get last hash uint a = m_hash[0]; uint b = m_hash[1]; uint c = m_hash[2]; uint d = m_hash[3]; uint e = m_hash[4]; var words = new uint[80]; int current = startIndex; // convert to big endian for (int i = 0; i < 16; i++, current += 4) { words[i] = BitConverterEndian.ToUInt32BE(block, current); } // extend to 80 words for (int i = 16; i < 80; i++) { words[i] = (words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16]).Rol(1); } // first round for (int i = 0; i < 4; i++) { int offset = 5 * i; e += a.Rol(5) + F1(b, c, d) + words[offset] + 0x5a827999; b = b.Rol(30); d += e.Rol(5) + F1(a, b, c) + words[offset + 1] + 0x5a827999; a = a.Rol(30); c += d.Rol(5) + F1(e, a, b) + words[offset + 2] + 0x5a827999; e = e.Rol(30); b += c.Rol(5) + F1(d, e, a) + words[offset + 3] + 0x5a827999; d = d.Rol(30); a += b.Rol(5) + F1(c, d, e) + words[offset + 4] + 0x5a827999; c = c.Rol(30); } // second round for (int i = 4; i < 8; i++) { int offset = 5 * i; e += a.Rol(5) + F2(b, c, d) + words[offset] + 0x6ed9eba1; b = b.Rol(30); d += e.Rol(5) + F2(a, b, c) + words[offset + 1] + 0x6ed9eba1; a = a.Rol(30); c += d.Rol(5) + F2(e, a, b) + words[offset + 2] + 0x6ed9eba1; e = e.Rol(30); b += c.Rol(5) + F2(d, e, a) + words[offset + 3] + 0x6ed9eba1; d = d.Rol(30); a += b.Rol(5) + F2(c, d, e) + words[offset + 4] + 0x6ed9eba1; c = c.Rol(30); } // third round for (int i = 8; i < 12; i++) { int offset = 5 * i; e += a.Rol(5) + F3(b, c, d) + words[offset] + 0x8f1bbcdc; b = b.Rol(30); d += e.Rol(5) + F3(a, b, c) + words[offset + 1] + 0x8f1bbcdc; a = a.Rol(30); c += d.Rol(5) + F3(e, a, b) + words[offset + 2] + 0x8f1bbcdc; e = e.Rol(30); b += c.Rol(5) + F3(d, e, a) + words[offset + 3] + 0x8f1bbcdc; d = d.Rol(30); a += b.Rol(5) + F3(c, d, e) + words[offset + 4] + 0x8f1bbcdc; c = c.Rol(30); } // fourth round for (int i = 12; i < 16; i++) { int offset = 5 * i; e += a.Rol(5) + F2(b, c, d) + words[offset] + 0xca62c1d6; b = b.Rol(30); d += e.Rol(5) + F2(a, b, c) + words[offset + 1] + 0xca62c1d6; a = a.Rol(30); c += d.Rol(5) + F2(e, a, b) + words[offset + 2] + 0xca62c1d6; e = e.Rol(30); b += c.Rol(5) + F2(d, e, a) + words[offset + 3] + 0xca62c1d6; d = d.Rol(30); a += b.Rol(5) + F2(c, d, e) + words[offset + 4] + 0xca62c1d6; c = c.Rol(30); } // update hash m_hash[0] += a; m_hash[1] += b; m_hash[2] += c; m_hash[3] += d; m_hash[4] += e; }
private void ProcessBlock(byte[] block, int startIndex) { // get last hash uint a = m_hash[0]; uint b = m_hash[1]; uint c = m_hash[2]; uint d = m_hash[3]; // first round uint word0 = BitConverterEndian.ToUInt32LE(block, 0 * sizeof(uint)); a = (a + F1(b, c, d) + word0 + 0xd76aa478).Rol(7) + b; uint word1 = BitConverterEndian.ToUInt32LE(block, 1 * sizeof(uint)); d = (d + F1(a, b, c) + word1 + 0xe8c7b756).Rol(12) + a; uint word2 = BitConverterEndian.ToUInt32LE(block, 2 * sizeof(uint)); c = (c + F1(d, a, b) + word2 + 0x242070db).Rol(17) + d; uint word3 = BitConverterEndian.ToUInt32LE(block, 3 * sizeof(uint)); b = (b + F1(c, d, a) + word3 + 0xc1bdceee).Rol(22) + c; uint word4 = BitConverterEndian.ToUInt32LE(block, 4 * sizeof(uint)); a = (a + F1(b, c, d) + word4 + 0xf57c0faf).Rol(7) + b; uint word5 = BitConverterEndian.ToUInt32LE(block, 5 * sizeof(uint)); d = (d + F1(a, b, c) + word5 + 0x4787c62a).Rol(12) + a; uint word6 = BitConverterEndian.ToUInt32LE(block, 6 * sizeof(uint)); c = (c + F1(d, a, b) + word6 + 0xa8304613).Rol(17) + d; uint word7 = BitConverterEndian.ToUInt32LE(block, 7 * sizeof(uint)); b = (b + F1(c, d, a) + word7 + 0xfd469501).Rol(22) + c; uint word8 = BitConverterEndian.ToUInt32LE(block, 8 * sizeof(uint)); a = (a + F1(b, c, d) + word8 + 0x698098d8).Rol(7) + b; uint word9 = BitConverterEndian.ToUInt32LE(block, 9 * sizeof(uint)); d = (d + F1(a, b, c) + word9 + 0x8b44f7af).Rol(12) + a; uint word10 = BitConverterEndian.ToUInt32LE(block, 10 * sizeof(uint)); c = (c + F1(d, a, b) + word10 + 0xffff5bb1).Rol(17) + d; uint word11 = BitConverterEndian.ToUInt32LE(block, 11 * sizeof(uint)); b = (b + F1(c, d, a) + word11 + 0x895cd7be).Rol(22) + c; uint word12 = BitConverterEndian.ToUInt32LE(block, 12 * sizeof(uint)); a = (a + F1(b, c, d) + word12 + 0x6b901122).Rol(7) + b; uint word13 = BitConverterEndian.ToUInt32LE(block, 13 * sizeof(uint)); d = (d + F1(a, b, c) + word13 + 0xfd987193).Rol(12) + a; uint word14 = BitConverterEndian.ToUInt32LE(block, 14 * sizeof(uint)); c = (c + F1(d, a, b) + word14 + 0xa679438e).Rol(17) + d; uint word15 = BitConverterEndian.ToUInt32LE(block, 15 * sizeof(uint)); b = (b + F1(c, d, a) + word15 + 0x49b40821).Rol(22) + c; // second round a = (a + F2(b, c, d) + word1 + 0xf61e2562).Rol(5) + b; d = (d + F2(a, b, c) + word6 + 0xc040b340).Rol(9) + a; c = (c + F2(d, a, b) + word11 + 0x265e5a51).Rol(14) + d; b = (b + F2(c, d, a) + word0 + 0xe9b6c7aa).Rol(20) + c; a = (a + F2(b, c, d) + word5 + 0xd62f105d).Rol(5) + b; d = (d + F2(a, b, c) + word10 + 0x02441453).Rol(9) + a; c = (c + F2(d, a, b) + word15 + 0xd8a1e681).Rol(14) + d; b = (b + F2(c, d, a) + word4 + 0xe7d3fbc8).Rol(20) + c; a = (a + F2(b, c, d) + word9 + 0x21e1cde6).Rol(5) + b; d = (d + F2(a, b, c) + word14 + 0xc33707d6).Rol(9) + a; c = (c + F2(d, a, b) + word3 + 0xf4d50d87).Rol(14) + d; b = (b + F2(c, d, a) + word8 + 0x455a14ed).Rol(20) + c; a = (a + F2(b, c, d) + word13 + 0xa9e3e905).Rol(5) + b; d = (d + F2(a, b, c) + word2 + 0xfcefa3f8).Rol(9) + a; c = (c + F2(d, a, b) + word7 + 0x676f02d9).Rol(14) + d; b = (b + F2(c, d, a) + word12 + 0x8d2a4c8a).Rol(20) + c; // third round a = (a + F3(b, c, d) + word5 + 0xfffa3942).Rol(4) + b; d = (d + F3(a, b, c) + word8 + 0x8771f681).Rol(11) + a; c = (c + F3(d, a, b) + word11 + 0x6d9d6122).Rol(16) + d; b = (b + F3(c, d, a) + word14 + 0xfde5380c).Rol(23) + c; a = (a + F3(b, c, d) + word1 + 0xa4beea44).Rol(4) + b; d = (d + F3(a, b, c) + word4 + 0x4bdecfa9).Rol(11) + a; c = (c + F3(d, a, b) + word7 + 0xf6bb4b60).Rol(16) + d; b = (b + F3(c, d, a) + word10 + 0xbebfbc70).Rol(23) + c; a = (a + F3(b, c, d) + word13 + 0x289b7ec6).Rol(4) + b; d = (d + F3(a, b, c) + word0 + 0xeaa127fa).Rol(11) + a; c = (c + F3(d, a, b) + word3 + 0xd4ef3085).Rol(16) + d; b = (b + F3(c, d, a) + word6 + 0x04881d05).Rol(23) + c; a = (a + F3(b, c, d) + word9 + 0xd9d4d039).Rol(4) + b; d = (d + F3(a, b, c) + word12 + 0xe6db99e5).Rol(11) + a; c = (c + F3(d, a, b) + word15 + 0x1fa27cf8).Rol(16) + d; b = (b + F3(c, d, a) + word2 + 0xc4ac5665).Rol(23) + c; // fourth round a = (a + F4(b, c, d) + word0 + 0xf4292244).Rol(6) + b; d = (d + F4(a, b, c) + word7 + 0x432aff97).Rol(10) + a; c = (c + F4(d, a, b) + word14 + 0xab9423a7).Rol(15) + d; b = (b + F4(c, d, a) + word5 + 0xfc93a039).Rol(21) + c; a = (a + F4(b, c, d) + word12 + 0x655b59c3).Rol(6) + b; d = (d + F4(a, b, c) + word3 + 0x8f0ccc92).Rol(10) + a; c = (c + F4(d, a, b) + word10 + 0xffeff47d).Rol(15) + d; b = (b + F4(c, d, a) + word1 + 0x85845dd1).Rol(21) + c; a = (a + F4(b, c, d) + word8 + 0x6fa87e4f).Rol(6) + b; d = (d + F4(a, b, c) + word15 + 0xfe2ce6e0).Rol(10) + a; c = (c + F4(d, a, b) + word6 + 0xa3014314).Rol(15) + d; b = (b + F4(c, d, a) + word13 + 0x4e0811a1).Rol(21) + c; a = (a + F4(b, c, d) + word4 + 0xf7537e82).Rol(6) + b; d = (d + F4(a, b, c) + word11 + 0xbd3af235).Rol(10) + a; c = (c + F4(d, a, b) + word2 + 0x2ad7d2bb).Rol(15) + d; b = (b + F4(c, d, a) + word9 + 0xeb86d391).Rol(21) + c; // update hash m_hash[0] += a; m_hash[1] += b; m_hash[2] += c; m_hash[3] += d; }
private void ProcessBlock(byte[] block, int startIndex) { // get last hash uint a = m_hash[0]; uint b = m_hash[1]; uint c = m_hash[2]; uint d = m_hash[3]; uint e = m_hash[4]; uint f = m_hash[5]; uint g = m_hash[6]; uint h = m_hash[7]; // data represented as 16x 32-bit words var words = new uint[64]; int current = startIndex; // convert to big endian for (int j = 0; j < 16; j++, current += 4) { words[j] = BitConverterEndian.ToUInt32BE(block, current); } uint x, y; // temporaries // first round x = h + F1(e, f, g) + 0x428a2f98 + words[0]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0x71374491 + words[1]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0xb5c0fbcf + words[2]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0xe9b5dba5 + words[3]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0x3956c25b + words[4]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0x59f111f1 + words[5]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0x923f82a4 + words[6]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0xab1c5ed5 + words[7]; y = F2(b, c, d); e += x; a = x + y; // secound round x = h + F1(e, f, g) + 0xd807aa98 + words[8]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0x12835b01 + words[9]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0x243185be + words[10]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0x550c7dc3 + words[11]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0x72be5d74 + words[12]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0x80deb1fe + words[13]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0x9bdc06a7 + words[14]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0xc19bf174 + words[15]; y = F2(b, c, d); e += x; a = x + y; int i = 16; // extend to 24 words for (; i < 24; i++) { words[i] = words[i - 16] + (words[i - 15].Ror(7) ^ words[i - 15].Ror(18) ^ (words[i - 15] >> 3)) + words[i - 7] + (words[i - 2].Ror(17) ^ words[i - 2].Ror(19) ^ (words[i - 2] >> 10)); } // third round x = h + F1(e, f, g) + 0xe49b69c1 + words[16]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0xefbe4786 + words[17]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0x0fc19dc6 + words[18]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0x240ca1cc + words[19]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0x2de92c6f + words[20]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0x4a7484aa + words[21]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0x5cb0a9dc + words[22]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0x76f988da + words[23]; y = F2(b, c, d); e += x; a = x + y; // extend to 32 words for (; i < 32; i++) { words[i] = words[i - 16] + (words[i - 15].Ror(7) ^ words[i - 15].Ror(18) ^ (words[i - 15] >> 3)) + words[i - 7] + (words[i - 2].Ror(17) ^ words[i - 2].Ror(19) ^ (words[i - 2] >> 10)); } // fourth round x = h + F1(e, f, g) + 0x983e5152 + words[24]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0xa831c66d + words[25]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0xb00327c8 + words[26]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0xbf597fc7 + words[27]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0xc6e00bf3 + words[28]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0xd5a79147 + words[29]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0x06ca6351 + words[30]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0x14292967 + words[31]; y = F2(b, c, d); e += x; a = x + y; // extend to 40 words for (; i < 40; i++) { words[i] = words[i - 16] + (words[i - 15].Ror(7) ^ words[i - 15].Ror(18) ^ (words[i - 15] >> 3)) + words[i - 7] + (words[i - 2].Ror(17) ^ words[i - 2].Ror(19) ^ (words[i - 2] >> 10)); } // fifth round x = h + F1(e, f, g) + 0x27b70a85 + words[32]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0x2e1b2138 + words[33]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0x4d2c6dfc + words[34]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0x53380d13 + words[35]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0x650a7354 + words[36]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0x766a0abb + words[37]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0x81c2c92e + words[38]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0x92722c85 + words[39]; y = F2(b, c, d); e += x; a = x + y; // extend to 48 words for (; i < 48; i++) { words[i] = words[i - 16] + (words[i - 15].Ror(7) ^ words[i - 15].Ror(18) ^ (words[i - 15] >> 3)) + words[i - 7] + (words[i - 2].Ror(17) ^ words[i - 2].Ror(19) ^ (words[i - 2] >> 10)); } // sixth round x = h + F1(e, f, g) + 0xa2bfe8a1 + words[40]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0xa81a664b + words[41]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0xc24b8b70 + words[42]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0xc76c51a3 + words[43]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0xd192e819 + words[44]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0xd6990624 + words[45]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0xf40e3585 + words[46]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0x106aa070 + words[47]; y = F2(b, c, d); e += x; a = x + y; // extend to 56 words for (; i < 56; i++) { words[i] = words[i - 16] + (words[i - 15].Ror(7) ^ words[i - 15].Ror(18) ^ (words[i - 15] >> 3)) + words[i - 7] + (words[i - 2].Ror(17) ^ words[i - 2].Ror(19) ^ (words[i - 2] >> 10)); } // seventh round x = h + F1(e, f, g) + 0x19a4c116 + words[48]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0x1e376c08 + words[49]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0x2748774c + words[50]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0x34b0bcb5 + words[51]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0x391c0cb3 + words[52]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0x4ed8aa4a + words[53]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0x5b9cca4f + words[54]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0x682e6ff3 + words[55]; y = F2(b, c, d); e += x; a = x + y; // extend to 64 words for (; i < 64; i++) { words[i] = words[i - 16] + (words[i - 15].Ror(7) ^ words[i - 15].Ror(18) ^ (words[i - 15] >> 3)) + words[i - 7] + (words[i - 2].Ror(17) ^ words[i - 2].Ror(19) ^ (words[i - 2] >> 10)); } // eigth round x = h + F1(e, f, g) + 0x748f82ee + words[56]; y = F2(a, b, c); d += x; h = x + y; x = g + F1(d, e, f) + 0x78a5636f + words[57]; y = F2(h, a, b); c += x; g = x + y; x = f + F1(c, d, e) + 0x84c87814 + words[58]; y = F2(g, h, a); b += x; f = x + y; x = e + F1(b, c, d) + 0x8cc70208 + words[59]; y = F2(f, g, h); a += x; e = x + y; x = d + F1(a, b, c) + 0x90befffa + words[60]; y = F2(e, f, g); h += x; d = x + y; x = c + F1(h, a, b) + 0xa4506ceb + words[61]; y = F2(d, e, f); g += x; c = x + y; x = b + F1(g, h, a) + 0xbef9a3f7 + words[62]; y = F2(c, d, e); f += x; b = x + y; x = a + F1(f, g, h) + 0xc67178f2 + words[63]; y = F2(b, c, d); e += x; a = x + y; // update hash m_hash[0] += a; m_hash[1] += b; m_hash[2] += c; m_hash[3] += d; m_hash[4] += e; m_hash[5] += f; m_hash[6] += g; m_hash[7] += h; }