Пример #1
0
        private void ProcessBlock(ref SHA512_DATA sha, byte[] block)
        {
            ulong[] W = new ulong[80];
            ulong   a, b, c, d, e, f, g, h;
            ulong   temp, temp2;
            int     t;

            /* Unpack the block into 80 64-bit words */
            for (t = 0; t < 16; ++t)
            {
                W[t] = (((ulong)(block[t * 8 + 0])) << 56) |
                       (((ulong)(block[t * 8 + 1])) << 48) |
                       (((ulong)(block[t * 8 + 2])) << 40) |
                       (((ulong)(block[t * 8 + 3])) << 32) |
                       (((ulong)(block[t * 8 + 4])) << 24) |
                       (((ulong)(block[t * 8 + 5])) << 16) |
                       (((ulong)(block[t * 8 + 6])) << 8) |
                       ((ulong)(block[t * 8 + 7]));
            }
            for (t = 16; t < 80; ++t)
            {
                W[t] = RHO1(W[t - 2]) + W[t - 7] +
                       RHO0(W[t - 15]) + W[t - 16];
            }

            /* Load the SHA-512 state into local variables */
            a = sha.A;
            b = sha.B;
            c = sha.C;
            d = sha.D;
            e = sha.E;
            f = sha.F;
            g = sha.G;
            h = sha.H;

            /* Perform 80 rounds of hash computations */
            for (t = 0; t < 80; ++t)
            {
                temp  = h + SUM1(e) + CH(e, f, g) + K[t] + W[t];
                temp2 = SUM0(a) + MAJ(a, b, c);
                h     = g;
                g     = f;
                f     = e;
                e     = d + temp;
                d     = c;
                c     = b;
                b     = a;
                a     = temp + temp2;
            }

            /* Combine the previous SHA-512 state with the new state */
            sha.A += a;
            sha.B += b;
            sha.C += c;
            sha.D += d;
            sha.E += e;
            sha.F += f;
            sha.G += g;
            sha.H += h;
        }
Пример #2
0
        public void Sha512_data(ref SHA512_DATA sha, ref byte[] buffer, uint len)
        {
            uint templen;

            /* Add to the total length of the input stream */
            sha.totalLen += (ulong)len;

            /* Copy the blocks into the input buffer and process them */
            while (len > 0)
            {
                if ((sha.inputLen == 0) && len >= 128)
                {
                    /* Short cut: no point copying the data twice */
                    ProcessBlock(ref sha, buffer);
                    buffer = ChangeBufPointer(buffer, 128);
                    len   -= 128;
                }
                else
                {
                    templen = len;
                    if (templen > (128 - sha.inputLen))
                    {
                        templen = 128 - sha.inputLen;
                    }
                    BufCopy(ref sha.input, sha.inputLen, buffer, 0, templen);
                    if ((sha.inputLen += templen) >= 128)
                    {
                        ProcessBlock(ref sha, sha.input);
                        sha.inputLen = 0;
                    }
                    buffer = ChangeBufPointer(buffer, templen);
                    len   -= templen;
                }
            }
        }
Пример #3
0
 private void Sha512_init(ref SHA512_DATA sha)
 {
     sha.input    = new byte[128];
     sha.inputLen = 0;
     sha.A        = (ulong)(0x6a09e667f3bcc908);
     sha.B        = (ulong)(0xbb67ae8584caa73b);
     sha.C        = (ulong)(0x3c6ef372fe94f82b);
     sha.D        = (ulong)(0xa54ff53a5f1d36f1);
     sha.E        = (ulong)(0x510e527fade682d1);
     sha.F        = (ulong)(0x9b05688c2b3e6c1f);
     sha.G        = (ulong)(0x1f83d9abfb41bd6b);
     sha.H        = (ulong)(0x5be0cd19137e2179);
     sha.totalLen = 0;
 }
Пример #4
0
        public void Sha512_finalize(ref SHA512_DATA sha, byte[] hash)
        {
            ulong totalBits;

            /* Compute the final hash if necessary */
            /* Pad the input data to a multiple of 1024 bits */
            if (sha.inputLen >= (128 - 16))
            {
                /* Need two blocks worth of padding */
                sha.input[(sha.inputLen)++] = (byte)0x80;
                while (sha.inputLen < 128)
                {
                    sha.input[(sha.inputLen)++] = (byte)0x00;
                }
                ProcessBlock(ref sha, sha.input);
                sha.inputLen = 0;
            }
            else
            {
                /* Need one block worth of padding */
                sha.input[(sha.inputLen)++] = (byte)0x80;
            }
            while (sha.inputLen < (128 - 16))
            {
                sha.input[(sha.inputLen)++] = (byte)0x00;
            }
            totalBits = (sha.totalLen << 3);
            BufSet(ref sha.input, (128 - 16), 0, 8);
            WriteLong(sha.input, 128 - 8, totalBits);
            ProcessBlock(ref sha, sha.input);

            /* Write the final hash value to the supplied buffer */
            if (hash != null)
            {
                WriteLong(hash, 0, sha.A);
                WriteLong(hash, 8, sha.B);
                WriteLong(hash, 16, sha.C);
                WriteLong(hash, 24, sha.D);
                WriteLong(hash, 32, sha.E);
                WriteLong(hash, 40, sha.F);
                WriteLong(hash, 48, sha.G);
                WriteLong(hash, 56, sha.H);
            }
        }