Exemple #1
0
        protected override void Blocks(byte[] m, int offset, int count)
        {
            unchecked
            {
                UInt64  hibit = m_final ? 0 : ((UInt64)1 << 40); /* 1 << 128 */
                UInt64  r0, r1, r2;
                UInt64  s1, s2;
                UInt64  h0, h1, h2;
                UInt64  c;
                UInt128 d0 = new UInt128();
                UInt128 d1 = new UInt128();
                UInt128 d2 = new UInt128();

                r0 = m_r[0];
                r1 = m_r[1];
                r2 = m_r[2];

                h0 = m_h[0];
                h1 = m_h[1];
                h2 = m_h[2];

                s1 = r1 * (5 << 2);
                s2 = r2 * (5 << 2);

                while (count >= BlockSize)
                {
                    UInt64 t0, t1;

                    /* h += m[i] */
                    t0 = BytesToInt64(m, offset);
                    t1 = BytesToInt64(m, 8 + offset);

                    h0 += ((t0) & 0xfffffffffff);
                    h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
                    h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit;

                    /* h *= r */
                    d0.SetMultiplyUInt64(ref h0, ref r0);
                    d0.AddMultiplyUInt64(ref h1, ref s2);
                    d0.AddMultiplyUInt64(ref h2, ref s1);

                    d1.SetMultiplyUInt64(ref h0, ref r1);
                    d1.AddMultiplyUInt64(ref h1, ref r0);
                    d1.AddMultiplyUInt64(ref h2, ref s2);

                    d2.SetMultiplyUInt64(ref h0, ref r2);
                    d2.AddMultiplyUInt64(ref h1, ref r1);
                    d2.AddMultiplyUInt64(ref h2, ref r0);

                    /* (partial) h %= p */
                    c  = (d0 >> 44).Low;
                    h0 = d0.Low & 0xfffffffffff;

                    d1.Add(c);
                    c  = (d1 >> 44).Low;
                    h1 = d1.Low & 0xfffffffffff;

                    d2.Add(c);
                    c  = (d2 >> 42).Low;
                    h2 = d2.Low & 0x3ffffffffff;

                    h0 += c * 5;
                    c   = (h0 >> 44);
                    h0  = h0 & 0xfffffffffff;
                    h1 += c;

                    offset += BlockSize;
                    count  -= BlockSize;
                }

                m_h[0] = h0;
                m_h[1] = h1;
                m_h[2] = h2;
            }
        }