private void Compress(ReadOnlySpan <byte> data, uint finalizer) { var dataAsUInt = MemoryMarshal.Cast <byte, uint>(data); var h0 = m_h0; var h1 = m_h1; var h2 = m_h2; var h3 = m_h3; var h4 = m_h4; var r0 = m_r0; var r1 = m_r1; var r2 = m_r2; var r3 = m_r3; var r4 = m_r4; var s0 = m_s0; var s1 = m_s1; var s2 = m_s2; var s3 = m_s3; var t0 = dataAsUInt[0]; var t1 = dataAsUInt[1]; var t2 = dataAsUInt[2]; var t3 = dataAsUInt[3]; h0 += (t0 & 0x3FFFFFFU); h1 += ((uint)((BitwiseHelpers.ConcatBits(t1, t0) >> 26) & 0x3FFFFFFU)); h2 += ((uint)((BitwiseHelpers.ConcatBits(t2, t1) >> 20) & 0x3FFFFFFU)); h3 += ((uint)((BitwiseHelpers.ConcatBits(t3, t2) >> 14) & 0x3FFFFFFU)); h4 += ((uint)BitwiseHelpers.Add((t3 >> 8), finalizer)); var d0 = (BitwiseHelpers.Multiply(h0, r0) + BitwiseHelpers.Multiply(h1, s3) + BitwiseHelpers.Multiply(h2, s2) + BitwiseHelpers.Multiply(h3, s1) + BitwiseHelpers.Multiply(h4, s0)); var d1 = (BitwiseHelpers.Multiply(h0, r1) + BitwiseHelpers.Multiply(h1, r0) + BitwiseHelpers.Multiply(h2, s3) + BitwiseHelpers.Multiply(h3, s2) + BitwiseHelpers.Multiply(h4, s1)); var d2 = (BitwiseHelpers.Multiply(h0, r2) + BitwiseHelpers.Multiply(h1, r1) + BitwiseHelpers.Multiply(h2, r0) + BitwiseHelpers.Multiply(h3, s3) + BitwiseHelpers.Multiply(h4, s2)); var d3 = (BitwiseHelpers.Multiply(h0, r3) + BitwiseHelpers.Multiply(h1, r2) + BitwiseHelpers.Multiply(h2, r1) + BitwiseHelpers.Multiply(h3, r0) + BitwiseHelpers.Multiply(h4, s3)); var d4 = (BitwiseHelpers.Multiply(h0, r4) + BitwiseHelpers.Multiply(h1, r3) + BitwiseHelpers.Multiply(h2, r2) + BitwiseHelpers.Multiply(h3, r1) + BitwiseHelpers.Multiply(h4, r0)); var c = (d0 >> 26); h0 = ((uint)(d0 & 0x3FFFFFFU)); d1 += c; c = (d1 >> 26); h1 = ((uint)(d1 & 0x3FFFFFFU)); d2 += c; c = (d2 >> 26); h2 = ((uint)(d2 & 0x3FFFFFFU)); d3 += c; c = (d3 >> 26); h3 = ((uint)(d3 & 0x3FFFFFFU)); d4 += c; c = (d4 >> 26); h4 = ((uint)(d4 & 0x3FFFFFFU)); h0 += ((uint)(c * 5UL)); c = (h0 >> 26); h0 = (h0 & 0x3FFFFFFU); h1 += ((uint)c); m_h0 = h0; m_h1 = h1; m_h2 = h2; m_h3 = h3; m_h4 = h4; }
/// <summary> /// Finalizes the hash computation after the last data is processed by the cryptographic stream object. /// </summary> protected override byte[] HashFinal() { var h0 = m_h0; var h1 = m_h1; var h2 = m_h2; var h3 = m_h3; var h4 = m_h4; var k0 = m_k0; var k1 = m_k1; var k2 = m_k2; var k3 = m_k3; h1 += (h0 >> 26); h0 &= 0x3FFFFFFU; h2 += (h1 >> 26); h1 &= 0x3FFFFFFU; h3 += (h2 >> 26); h2 &= 0x3FFFFFFU; h4 += (h3 >> 26); h3 &= 0x3FFFFFFU; h0 += ((h4 >> 26) * 5U); h4 &= 0x3FFFFFFU; h1 += (h0 >> 26); h0 &= 0x3FFFFFFU; uint g0; uint g1; uint g2; uint g3; uint g4; uint x; uint y; g0 = (h0 + 5U); x = (g0 >> 26); g0 &= 0x3FFFFFFU; g1 = (h1 + x); x = (g1 >> 26); g1 &= 0x3FFFFFFU; g2 = (h2 + x); x = (g2 >> 26); g2 &= 0x3FFFFFFU; g3 = (h3 + x); x = (g3 >> 26); g3 &= 0x3FFFFFFU; g4 = ((h4 + x) - (1 << 26)); x = ((g4 >> ((sizeof(uint) * 8) - 1)) - 1U); y = ~x; h0 = ((h0 & y) | (g0 & x)); h1 = ((h1 & y) | (g1 & x)); h2 = ((h2 & y) | (g2 & x)); h3 = ((h3 & y) | (g3 & x)); h4 = ((h4 & y) | (g4 & x)); var f0 = BitwiseHelpers.Add(((h0) | (h1 << 26)), k0); var f1 = BitwiseHelpers.Add(((h1 >> 6) | (h2 << 20)), k1); var f2 = BitwiseHelpers.Add(((h2 >> 12) | (h3 << 14)), k2); var f3 = BitwiseHelpers.Add(((h3 >> 18) | (h4 << 8)), k3); m_h0 = ((uint)f0); f1 += (f0 >> 32); m_h1 = ((uint)f1); f2 += (f1 >> 32); m_h2 = ((uint)f2); f3 += (f2 >> 32); m_h3 = ((uint)f3); m_h4 = 0U; var result = new byte[BlockLength]; var resultAsUInt = MemoryMarshal.Cast <byte, uint>(result); resultAsUInt[0] = m_h0; resultAsUInt[1] = m_h1; resultAsUInt[2] = m_h2; resultAsUInt[3] = m_h3; return(result); }