Example #1
0
        public static unsafe void GetDigest(byte *input, int length, Md5Digest *digest)
        {
            const int bytesPerBlock = 64;
            var       blocksCount   = (length + 8) / bytesPerBlock + 1;

            digest->A = 0x67452301;
            digest->B = 0xefcdab89;
            digest->C = 0x98badcfe;
            digest->D = 0x10325476;

            var paddingBlockData = default(Block);

            for (var blockIndex = 0; blockIndex < blocksCount; blockIndex++)
            {
                var offset   = blockIndex * bytesPerBlock;
                var blockEnd = offset + bytesPerBlock;

                uint *blockPtr;

                if (blockEnd > length)    // we're going to run out of input on this block
                {
                    if (offset >= length) // we're already totally past the input at this point - this block is just padding, and definitely the final block
                    {
                        if (offset == length)
                        {
                            // the end of input perfectly lined up with a block - so this is the start of padding
                            *(byte *)&paddingBlockData = 0x80;
                        }
                        else
                        {
                            // this is not the start of padding, so we need to clear out any data from the first padding block
                            paddingBlockData = default(Block);
                        }

                        paddingBlockData.SetOriginalLength(length);
                    }
                    else // there is still some input left to consume before we get to padding
                    {
                        var bytesRemaining = bytesPerBlock - (blockEnd - length);
                        var paddingPtr     = (byte *)&paddingBlockData;
                        Common.UnsafeMemoryCopy(&input[offset], paddingPtr, bytesRemaining);

                        // add bit
                        paddingPtr[bytesRemaining] = 0x80;

                        // check if we can add the length
                        if (bytesPerBlock - (bytesRemaining + 1) >= 8)
                        {
                            paddingBlockData.SetOriginalLength(length);
                        }
                    }

                    blockPtr = (uint *)&paddingBlockData;
                }
                else
                {
                    blockPtr = (uint *)&input[offset];
                }

                var a = digest->A;
                var b = digest->B;
                var c = digest->C;
                var d = digest->D;

                uint f, dTemp;

                // 0
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xd76aa478 + blockPtr[0], 7);
                a     = dTemp;

                // 1
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xe8c7b756 + blockPtr[1], 12);
                a     = dTemp;

                // 2
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x242070db + blockPtr[2], 17);
                a     = dTemp;

                // 3
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xc1bdceee + blockPtr[3], 22);
                a     = dTemp;

                // 4
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xf57c0faf + blockPtr[4], 7);
                a     = dTemp;

                // 5
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x4787c62a + blockPtr[5], 12);
                a     = dTemp;

                // 6
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xa8304613 + blockPtr[6], 17);
                a     = dTemp;

                // 7
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfd469501 + blockPtr[7], 22);
                a     = dTemp;

                // 8
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x698098d8 + blockPtr[8], 7);
                a     = dTemp;

                // 9
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x8b44f7af + blockPtr[9], 12);
                a     = dTemp;

                // 10
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xffff5bb1 + blockPtr[10], 17);
                a     = dTemp;

                // 11
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x895cd7be + blockPtr[11], 22);
                a     = dTemp;

                // 12
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x6b901122 + blockPtr[12], 7);
                a     = dTemp;

                // 13
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfd987193 + blockPtr[13], 12);
                a     = dTemp;

                // 14
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xa679438e + blockPtr[14], 17);
                a     = dTemp;

                // 15
                f     = (b & c) | (~b & d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x49b40821 + blockPtr[15], 22);
                a     = dTemp;


                // 16
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xf61e2562 + blockPtr[(5 * 16 + 1) % 16], 5);
                a     = dTemp;

                // 17
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xc040b340 + blockPtr[(5 * 17 + 1) % 16], 9);
                a     = dTemp;

                // 18
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x265e5a51 + blockPtr[(5 * 18 + 1) % 16], 14);
                a     = dTemp;

                // 19
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xe9b6c7aa + blockPtr[(5 * 19 + 1) % 16], 20);
                a     = dTemp;

                // 20
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xd62f105d + blockPtr[(5 * 20 + 1) % 16], 5);
                a     = dTemp;

                // 21
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x2441453 + blockPtr[(5 * 21 + 1) % 16], 9);
                a     = dTemp;

                // 22
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xd8a1e681 + blockPtr[(5 * 22 + 1) % 16], 14);
                a     = dTemp;

                // 23
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xe7d3fbc8 + blockPtr[(5 * 23 + 1) % 16], 20);
                a     = dTemp;

                // 24
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x21e1cde6 + blockPtr[(5 * 24 + 1) % 16], 5);
                a     = dTemp;

                // 25
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xc33707d6 + blockPtr[(5 * 25 + 1) % 16], 9);
                a     = dTemp;

                // 26
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xf4d50d87 + blockPtr[(5 * 26 + 1) % 16], 14);
                a     = dTemp;

                // 27
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x455a14ed + blockPtr[(5 * 27 + 1) % 16], 20);
                a     = dTemp;

                // 28
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xa9e3e905 + blockPtr[(5 * 28 + 1) % 16], 5);
                a     = dTemp;

                // 29
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfcefa3f8 + blockPtr[(5 * 29 + 1) % 16], 9);
                a     = dTemp;

                // 30
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x676f02d9 + blockPtr[(5 * 30 + 1) % 16], 14);
                a     = dTemp;

                // 31
                f     = (d & b) | (~d & c);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x8d2a4c8a + blockPtr[(5 * 31 + 1) % 16], 20);
                a     = dTemp;


                // 32
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfffa3942 + blockPtr[(3 * 32 + 5) % 16], 4);
                a     = dTemp;

                // 33
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x8771f681 + blockPtr[(3 * 33 + 5) % 16], 11);
                a     = dTemp;

                // 34
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x6d9d6122 + blockPtr[(3 * 34 + 5) % 16], 16);
                a     = dTemp;

                // 35
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfde5380c + blockPtr[(3 * 35 + 5) % 16], 23);
                a     = dTemp;

                // 36
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xa4beea44 + blockPtr[(3 * 36 + 5) % 16], 4);
                a     = dTemp;

                // 37
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x4bdecfa9 + blockPtr[(3 * 37 + 5) % 16], 11);
                a     = dTemp;

                // 38
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xf6bb4b60 + blockPtr[(3 * 38 + 5) % 16], 16);
                a     = dTemp;

                // 39
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xbebfbc70 + blockPtr[(3 * 39 + 5) % 16], 23);
                a     = dTemp;

                // 40
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x289b7ec6 + blockPtr[(3 * 40 + 5) % 16], 4);
                a     = dTemp;

                // 41
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xeaa127fa + blockPtr[(3 * 41 + 5) % 16], 11);
                a     = dTemp;

                // 42
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xd4ef3085 + blockPtr[(3 * 42 + 5) % 16], 16);
                a     = dTemp;

                // 43
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x4881d05 + blockPtr[(3 * 43 + 5) % 16], 23);
                a     = dTemp;

                // 44
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xd9d4d039 + blockPtr[(3 * 44 + 5) % 16], 4);
                a     = dTemp;

                // 45
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xe6db99e5 + blockPtr[(3 * 45 + 5) % 16], 11);
                a     = dTemp;

                // 46
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x1fa27cf8 + blockPtr[(3 * 46 + 5) % 16], 16);
                a     = dTemp;

                // 47
                f     = b ^ c ^ d;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xc4ac5665 + blockPtr[(3 * 47 + 5) % 16], 23);
                a     = dTemp;


                // 48
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xf4292244 + blockPtr[(7 * 48) % 16], 6);
                a     = dTemp;

                // 49
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x432aff97 + blockPtr[(7 * 49) % 16], 10);
                a     = dTemp;

                // 50
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xab9423a7 + blockPtr[(7 * 50) % 16], 15);
                a     = dTemp;

                // 51
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfc93a039 + blockPtr[(7 * 51) % 16], 21);
                a     = dTemp;

                // 52
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x655b59c3 + blockPtr[(7 * 52) % 16], 6);
                a     = dTemp;

                // 53
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x8f0ccc92 + blockPtr[(7 * 53) % 16], 10);
                a     = dTemp;

                // 54
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xffeff47d + blockPtr[(7 * 54) % 16], 15);
                a     = dTemp;

                // 55
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x85845dd1 + blockPtr[(7 * 55) % 16], 21);
                a     = dTemp;

                // 56
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x6fa87e4f + blockPtr[(7 * 56) % 16], 6);
                a     = dTemp;

                // 57
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xfe2ce6e0 + blockPtr[(7 * 57) % 16], 10);
                a     = dTemp;

                // 58
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xa3014314 + blockPtr[(7 * 58) % 16], 15);
                a     = dTemp;

                // 59
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x4e0811a1 + blockPtr[(7 * 59) % 16], 21);
                a     = dTemp;

                // 60
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xf7537e82 + blockPtr[(7 * 60) % 16], 6);
                a     = dTemp;

                // 61
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xbd3af235 + blockPtr[(7 * 61) % 16], 10);
                a     = dTemp;

                // 62
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0x2ad7d2bb + blockPtr[(7 * 62) % 16], 15);
                a     = dTemp;

                // 63
                f     = c ^ (b | ~d);
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + 0xeb86d391 + blockPtr[(7 * 63) % 16], 21);
                a     = dTemp;

                digest->A += a;
                digest->B += b;
                digest->C += c;
                digest->D += d;
            }
        }
Example #2
0
        public static unsafe void GetDigest(byte *input, int length, Md5Digest *digest)
        {
            const int bytesPerBlock = 64;
            var       blocksCount   = (length + 8) / bytesPerBlock + 1;

            digest->A = 0x67452301;
            digest->B = 0xefcdab89;
            digest->C = 0x98badcfe;
            digest->D = 0x10325476;

            var paddingBlockData = default(Block);

            for (var blockIndex = 0; blockIndex < blocksCount; blockIndex++)
            {
                var offset   = blockIndex * bytesPerBlock;
                var blockEnd = offset + bytesPerBlock;

                uint *blockPtr;

                if (blockEnd > length)    // we're going to run out of input on this block
                {
                    if (offset >= length) // we're already totally past the input at this point - this block is just padding, and definitely the final block
                    {
                        if (offset == length)
                        {
                            // the end of input perfectly lined up with a block - so this is the start of padding
                            *(byte *)&paddingBlockData = 0x80;
                        }
                        else
                        {
                            // this is not the start of padding, so we need to clear out any data from the first padding block
                            paddingBlockData = default(Block);
                        }

                        paddingBlockData.SetOriginalLength(length);
                    }
                    else // there is still some input left to consume before we get to padding
                    {
                        var bytesRemaining = bytesPerBlock - (blockEnd - length);
                        var paddingPtr     = (byte *)&paddingBlockData;
                        Common.UnsafeMemoryCopy(&input[offset], paddingPtr, bytesRemaining);

                        // add bit
                        paddingPtr[bytesRemaining] = 0x80;

                        // check if we can add the length
                        if (bytesPerBlock - (bytesRemaining + 1) >= 8)
                        {
                            paddingBlockData.SetOriginalLength(length);
                        }
                    }

                    blockPtr = (uint *)&paddingBlockData;
                }
                else
                {
                    blockPtr = (uint *)&input[offset];
                }

                var a = digest->A;
                var b = digest->B;
                var c = digest->C;
                var d = digest->D;

                uint f;

                // 0 (a, b, c, d)
                f  = (c ^ d) & b ^ d;
                a += f + 0xd76aa478 + blockPtr[0];
                a  = b + ((a << 7) | (a >> (32 - 7)));

                // 1 (d, a, b, c)
                f  = (b ^ c) & a ^ c;
                d += f + 0xe8c7b756 + blockPtr[1];
                d  = a + ((d << 12) | (d >> (32 - 12)));

                // 2 (c, d, a, b)
                f  = (a ^ b) & d ^ b;
                c += f + 0x242070db + blockPtr[2];
                c  = d + ((c << 17) | (c >> (32 - 17)));

                // 3 (b, c, d, a)
                f  = (d ^ a) & c ^ a;
                b += f + 0xc1bdceee + blockPtr[3];
                b  = c + ((b << 22) | (b >> (32 - 22)));

                // 4 (a, b, c, d)
                f  = (c ^ d) & b ^ d;
                a += f + 0xf57c0faf + blockPtr[4];
                a  = b + ((a << 7) | (a >> (32 - 7)));

                // 5 (d, a, b, c)
                f  = (b ^ c) & a ^ c;
                d += f + 0x4787c62a + blockPtr[5];
                d  = a + ((d << 12) | (d >> (32 - 12)));

                // 6 (c, d, a, b)
                f  = (a ^ b) & d ^ b;
                c += f + 0xa8304613 + blockPtr[6];
                c  = d + ((c << 17) | (c >> (32 - 17)));

                // 7 (b, c, d, a)
                f  = (d ^ a) & c ^ a;
                b += f + 0xfd469501 + blockPtr[7];
                b  = c + ((b << 22) | (b >> (32 - 22)));

                // 8 (a, b, c, d)
                f  = (c ^ d) & b ^ d;
                a += f + 0x698098d8 + blockPtr[8];
                a  = b + ((a << 7) | (a >> (32 - 7)));

                // 9 (d, a, b, c)
                f  = (b ^ c) & a ^ c;
                d += f + 0x8b44f7af + blockPtr[9];
                d  = a + ((d << 12) | (d >> (32 - 12)));

                // 10 (c, d, a, b)
                f  = (a ^ b) & d ^ b;
                c += f + 0xffff5bb1 + blockPtr[10];
                c  = d + ((c << 17) | (c >> (32 - 17)));

                // 11 (b, c, d, a)
                f  = (d ^ a) & c ^ a;
                b += f + 0x895cd7be + blockPtr[11];
                b  = c + ((b << 22) | (b >> (32 - 22)));

                // 12 (a, b, c, d)
                f  = (c ^ d) & b ^ d;
                a += f + 0x6b901122 + blockPtr[12];
                a  = b + ((a << 7) | (a >> (32 - 7)));

                // 13 (d, a, b, c)
                f  = (b ^ c) & a ^ c;
                d += f + 0xfd987193 + blockPtr[13];
                d  = a + ((d << 12) | (d >> (32 - 12)));

                // 14 (c, d, a, b)
                f  = (a ^ b) & d ^ b;
                c += f + 0xa679438e + blockPtr[14];
                c  = d + ((c << 17) | (c >> (32 - 17)));

                // 15 (b, c, d, a)
                f  = (d ^ a) & c ^ a;
                b += f + 0x49b40821 + blockPtr[15];
                b  = c + ((b << 22) | (b >> (32 - 22)));

                // 16 (a, b, c, d)
                f  = (b ^ c) & d ^ c;
                a += f + 0xf61e2562 + blockPtr[(5 * 16 + 1) & 0xf];
                a  = b + ((a << 5) | (a >> (32 - 5)));

                // 17 (d, a, b, c)
                f  = (a ^ b) & c ^ b;
                d += f + 0xc040b340 + blockPtr[(5 * 17 + 1) & 0xf];
                d  = a + ((d << 9) | (d >> (32 - 9)));

                // 18 (c, d, a, b)
                f  = (d ^ a) & b ^ a;
                c += f + 0x265e5a51 + blockPtr[(5 * 18 + 1) & 0xf];
                c  = d + ((c << 14) | (c >> (32 - 14)));

                // 19 (b, c, d, a)
                f  = (c ^ d) & a ^ d;
                b += f + 0xe9b6c7aa + blockPtr[(5 * 19 + 1) & 0xf];
                b  = c + ((b << 20) | (b >> (32 - 20)));

                // 20 (a, b, c, d)
                f  = (b ^ c) & d ^ c;
                a += f + 0xd62f105d + blockPtr[(5 * 20 + 1) & 0xf];
                a  = b + ((a << 5) | (a >> (32 - 5)));

                // 21 (d, a, b, c)
                f  = (a ^ b) & c ^ b;
                d += f + 0x2441453 + blockPtr[(5 * 21 + 1) & 0xf];
                d  = a + ((d << 9) | (d >> (32 - 9)));

                // 22 (c, d, a, b)
                f  = (d ^ a) & b ^ a;
                c += f + 0xd8a1e681 + blockPtr[(5 * 22 + 1) & 0xf];
                c  = d + ((c << 14) | (c >> (32 - 14)));

                // 23 (b, c, d, a)
                f  = (c ^ d) & a ^ d;
                b += f + 0xe7d3fbc8 + blockPtr[(5 * 23 + 1) & 0xf];
                b  = c + ((b << 20) | (b >> (32 - 20)));

                // 24 (a, b, c, d)
                f  = (b ^ c) & d ^ c;
                a += f + 0x21e1cde6 + blockPtr[(5 * 24 + 1) & 0xf];
                a  = b + ((a << 5) | (a >> (32 - 5)));

                // 25 (d, a, b, c)
                f  = (a ^ b) & c ^ b;
                d += f + 0xc33707d6 + blockPtr[(5 * 25 + 1) & 0xf];
                d  = a + ((d << 9) | (d >> (32 - 9)));

                // 26 (c, d, a, b)
                f  = (d ^ a) & b ^ a;
                c += f + 0xf4d50d87 + blockPtr[(5 * 26 + 1) & 0xf];
                c  = d + ((c << 14) | (c >> (32 - 14)));

                // 27 (b, c, d, a)
                f  = (c ^ d) & a ^ d;
                b += f + 0x455a14ed + blockPtr[(5 * 27 + 1) & 0xf];
                b  = c + ((b << 20) | (b >> (32 - 20)));

                // 28 (a, b, c, d)
                f  = (b ^ c) & d ^ c;
                a += f + 0xa9e3e905 + blockPtr[(5 * 28 + 1) & 0xf];
                a  = b + ((a << 5) | (a >> (32 - 5)));

                // 29 (d, a, b, c)
                f  = (a ^ b) & c ^ b;
                d += f + 0xfcefa3f8 + blockPtr[(5 * 29 + 1) & 0xf];
                d  = a + ((d << 9) | (d >> (32 - 9)));

                // 30 (c, d, a, b)
                f  = (d ^ a) & b ^ a;
                c += f + 0x676f02d9 + blockPtr[(5 * 30 + 1) & 0xf];
                c  = d + ((c << 14) | (c >> (32 - 14)));

                // 31 (b, c, d, a)
                f  = (c ^ d) & a ^ d;
                b += f + 0x8d2a4c8a + blockPtr[(5 * 31 + 1) & 0xf];
                b  = c + ((b << 20) | (b >> (32 - 20)));

                // 32 (a, b, c, d)
                f  = b ^ c ^ d;
                a += f + 0xfffa3942 + blockPtr[(3 * 32 + 5) & 0xf];
                a  = b + ((a << 4) | (a >> (32 - 4)));

                // 33 (d, a, b, c)
                f  = a ^ b ^ c;
                d += f + 0x8771f681 + blockPtr[(3 * 33 + 5) & 0xf];
                d  = a + ((d << 11) | (d >> (32 - 11)));

                // 34 (c, d, a, b)
                f  = d ^ a ^ b;
                c += f + 0x6d9d6122 + blockPtr[(3 * 34 + 5) & 0xf];
                c  = d + ((c << 16) | (c >> (32 - 16)));

                // 35 (b, c, d, a)
                f  = c ^ d ^ a;
                b += f + 0xfde5380c + blockPtr[(3 * 35 + 5) & 0xf];
                b  = c + ((b << 23) | (b >> (32 - 23)));

                // 36 (a, b, c, d)
                f  = b ^ c ^ d;
                a += f + 0xa4beea44 + blockPtr[(3 * 36 + 5) & 0xf];
                a  = b + ((a << 4) | (a >> (32 - 4)));

                // 37 (d, a, b, c)
                f  = a ^ b ^ c;
                d += f + 0x4bdecfa9 + blockPtr[(3 * 37 + 5) & 0xf];
                d  = a + ((d << 11) | (d >> (32 - 11)));

                // 38 (c, d, a, b)
                f  = d ^ a ^ b;
                c += f + 0xf6bb4b60 + blockPtr[(3 * 38 + 5) & 0xf];
                c  = d + ((c << 16) | (c >> (32 - 16)));

                // 39 (b, c, d, a)
                f  = c ^ d ^ a;
                b += f + 0xbebfbc70 + blockPtr[(3 * 39 + 5) & 0xf];
                b  = c + ((b << 23) | (b >> (32 - 23)));

                // 40 (a, b, c, d)
                f  = b ^ c ^ d;
                a += f + 0x289b7ec6 + blockPtr[(3 * 40 + 5) & 0xf];
                a  = b + ((a << 4) | (a >> (32 - 4)));

                // 41 (d, a, b, c)
                f  = a ^ b ^ c;
                d += f + 0xeaa127fa + blockPtr[(3 * 41 + 5) & 0xf];
                d  = a + ((d << 11) | (d >> (32 - 11)));

                // 42 (c, d, a, b)
                f  = d ^ a ^ b;
                c += f + 0xd4ef3085 + blockPtr[(3 * 42 + 5) & 0xf];
                c  = d + ((c << 16) | (c >> (32 - 16)));

                // 43 (b, c, d, a)
                f  = c ^ d ^ a;
                b += f + 0x4881d05 + blockPtr[(3 * 43 + 5) & 0xf];
                b  = c + ((b << 23) | (b >> (32 - 23)));

                // 44 (a, b, c, d)
                f  = b ^ c ^ d;
                a += f + 0xd9d4d039 + blockPtr[(3 * 44 + 5) & 0xf];
                a  = b + ((a << 4) | (a >> (32 - 4)));

                // 45 (d, a, b, c)
                f  = a ^ b ^ c;
                d += f + 0xe6db99e5 + blockPtr[(3 * 45 + 5) & 0xf];
                d  = a + ((d << 11) | (d >> (32 - 11)));

                // 46 (c, d, a, b)
                f  = d ^ a ^ b;
                c += f + 0x1fa27cf8 + blockPtr[(3 * 46 + 5) & 0xf];
                c  = d + ((c << 16) | (c >> (32 - 16)));

                // 47 (b, c, d, a)
                f  = c ^ d ^ a;
                b += f + 0xc4ac5665 + blockPtr[(3 * 47 + 5) & 0xf];
                b  = c + ((b << 23) | (b >> (32 - 23)));

                // 48 (a, b, c, d)
                f  = c ^ (b | ~d);
                a += f + 0xf4292244 + blockPtr[(7 * 48) & 0xf];
                a  = b + ((a << 6) | (a >> (32 - 6)));

                // 49 (d, a, b, c)
                f  = b ^ (a | ~c);
                d += f + 0x432aff97 + blockPtr[(7 * 49) & 0xf];
                d  = a + ((d << 10) | (d >> (32 - 10)));

                // 50 (c, d, a, b)
                f  = a ^ (d | ~b);
                c += f + 0xab9423a7 + blockPtr[(7 * 50) & 0xf];
                c  = d + ((c << 15) | (c >> (32 - 15)));

                // 51 (b, c, d, a)
                f  = d ^ (c | ~a);
                b += f + 0xfc93a039 + blockPtr[(7 * 51) & 0xf];
                b  = c + ((b << 21) | (b >> (32 - 21)));

                // 52 (a, b, c, d)
                f  = c ^ (b | ~d);
                a += f + 0x655b59c3 + blockPtr[(7 * 52) & 0xf];
                a  = b + ((a << 6) | (a >> (32 - 6)));

                // 53 (d, a, b, c)
                f  = b ^ (a | ~c);
                d += f + 0x8f0ccc92 + blockPtr[(7 * 53) & 0xf];
                d  = a + ((d << 10) | (d >> (32 - 10)));

                // 54 (c, d, a, b)
                f  = a ^ (d | ~b);
                c += f + 0xffeff47d + blockPtr[(7 * 54) & 0xf];
                c  = d + ((c << 15) | (c >> (32 - 15)));

                // 55 (b, c, d, a)
                f  = d ^ (c | ~a);
                b += f + 0x85845dd1 + blockPtr[(7 * 55) & 0xf];
                b  = c + ((b << 21) | (b >> (32 - 21)));

                // 56 (a, b, c, d)
                f  = c ^ (b | ~d);
                a += f + 0x6fa87e4f + blockPtr[(7 * 56) & 0xf];
                a  = b + ((a << 6) | (a >> (32 - 6)));

                // 57 (d, a, b, c)
                f  = b ^ (a | ~c);
                d += f + 0xfe2ce6e0 + blockPtr[(7 * 57) & 0xf];
                d  = a + ((d << 10) | (d >> (32 - 10)));

                // 58 (c, d, a, b)
                f  = a ^ (d | ~b);
                c += f + 0xa3014314 + blockPtr[(7 * 58) & 0xf];
                c  = d + ((c << 15) | (c >> (32 - 15)));

                // 59 (b, c, d, a)
                f  = d ^ (c | ~a);
                b += f + 0x4e0811a1 + blockPtr[(7 * 59) & 0xf];
                b  = c + ((b << 21) | (b >> (32 - 21)));

                // 60 (a, b, c, d)
                f  = c ^ (b | ~d);
                a += f + 0xf7537e82 + blockPtr[(7 * 60) & 0xf];
                a  = b + ((a << 6) | (a >> (32 - 6)));

                // 61 (d, a, b, c)
                f  = b ^ (a | ~c);
                d += f + 0xbd3af235 + blockPtr[(7 * 61) & 0xf];
                d  = a + ((d << 10) | (d >> (32 - 10)));

                // 62 (c, d, a, b)
                f  = a ^ (d | ~b);
                c += f + 0x2ad7d2bb + blockPtr[(7 * 62) & 0xf];
                c  = d + ((c << 15) | (c >> (32 - 15)));

                // 63 (b, c, d, a)
                f  = d ^ (c | ~a);
                b += f + 0xeb86d391 + blockPtr[(7 * 63) & 0xf];
                b  = c + ((b << 21) | (b >> (32 - 21)));

                digest->A += a;
                digest->B += b;
                digest->C += c;
                digest->D += d;
            }
        }
Example #3
0
        public static unsafe void GetDigest(byte *input, int length, Md5Digest *digest)
        {
            const int bytesPerBlock = 64;
            var       blocksCount   = (length + 8) / bytesPerBlock + 1;

            digest->A = 0x67452301;
            digest->B = 0xefcdab89;
            digest->C = 0x98badcfe;
            digest->D = 0x10325476;

            var paddingBlockData = default(Block);

            for (var blockIndex = 0; blockIndex < blocksCount; blockIndex++)
            {
                var offset   = blockIndex * bytesPerBlock;
                var blockEnd = offset + bytesPerBlock;

                uint *blockPtr;

                if (blockEnd > length)    // we're going to run out of input on this block
                {
                    if (offset >= length) // we're already totally past the input at this point - this block is just padding, and definitely the final block
                    {
                        if (offset == length)
                        {
                            // the end of input perfectly lined up with a block - so this is the start of padding
                            *(byte *)&paddingBlockData = 0x80;
                        }
                        else
                        {
                            // this is not the start of padding, so we need to clear out any data from the first padding block
                            paddingBlockData = default(Block);
                        }

                        paddingBlockData.SetOriginalLength(length);
                    }
                    else // there is still some input left to consume before we get to padding
                    {
                        var bytesRemaining = bytesPerBlock - (blockEnd - length);
                        var paddingPtr     = (byte *)&paddingBlockData;
                        Common.UnsafeMemoryCopy(&input[offset], paddingPtr, bytesRemaining);

                        // add bit
                        paddingPtr[bytesRemaining] = 0x80;

                        // check if we can add the length
                        if (bytesPerBlock - (bytesRemaining + 1) >= 8)
                        {
                            paddingBlockData.SetOriginalLength(length);
                        }
                    }

                    blockPtr = (uint *)&paddingBlockData;
                }
                else
                {
                    blockPtr = (uint *)&input[offset];
                }

                var a = digest->A;
                var b = digest->B;
                var c = digest->C;
                var d = digest->D;

                FF(ref a, b, c, d, blockPtr[0], 7, 0xd76aa478);                   // 0
                FF(ref d, a, b, c, blockPtr[1], 12, 0xe8c7b756);                  // 1
                FF(ref c, d, a, b, blockPtr[2], 17, 0x242070db);                  // 2
                FF(ref b, c, d, a, blockPtr[3], 22, 0xc1bdceee);                  // 3
                FF(ref a, b, c, d, blockPtr[4], 7, 0xf57c0faf);                   // 4
                FF(ref d, a, b, c, blockPtr[5], 12, 0x4787c62a);                  // 5
                FF(ref c, d, a, b, blockPtr[6], 17, 0xa8304613);                  // 6
                FF(ref b, c, d, a, blockPtr[7], 22, 0xfd469501);                  // 7
                FF(ref a, b, c, d, blockPtr[8], 7, 0x698098d8);                   // 8
                FF(ref d, a, b, c, blockPtr[9], 12, 0x8b44f7af);                  // 9
                FF(ref c, d, a, b, blockPtr[10], 17, 0xffff5bb1);                 // 10
                FF(ref b, c, d, a, blockPtr[11], 22, 0x895cd7be);                 // 11
                FF(ref a, b, c, d, blockPtr[12], 7, 0x6b901122);                  // 12
                FF(ref d, a, b, c, blockPtr[13], 12, 0xfd987193);                 // 13
                FF(ref c, d, a, b, blockPtr[14], 17, 0xa679438e);                 // 14
                FF(ref b, c, d, a, blockPtr[15], 22, 0x49b40821);                 // 15

                GG(ref a, b, c, d, blockPtr[(5 * 16 + 1) & 0xf], 5, 0xf61e2562);  // 16
                GG(ref d, a, b, c, blockPtr[(5 * 17 + 1) & 0xf], 9, 0xc040b340);  // 17
                GG(ref c, d, a, b, blockPtr[(5 * 18 + 1) & 0xf], 14, 0x265e5a51); // 18
                GG(ref b, c, d, a, blockPtr[(5 * 19 + 1) & 0xf], 20, 0xe9b6c7aa); // 19
                GG(ref a, b, c, d, blockPtr[(5 * 20 + 1) & 0xf], 5, 0xd62f105d);  // 20
                GG(ref d, a, b, c, blockPtr[(5 * 21 + 1) & 0xf], 9, 0x2441453);   // 21
                GG(ref c, d, a, b, blockPtr[(5 * 22 + 1) & 0xf], 14, 0xd8a1e681); // 22
                GG(ref b, c, d, a, blockPtr[(5 * 23 + 1) & 0xf], 20, 0xe7d3fbc8); // 23
                GG(ref a, b, c, d, blockPtr[(5 * 24 + 1) & 0xf], 5, 0x21e1cde6);  // 24
                GG(ref d, a, b, c, blockPtr[(5 * 25 + 1) & 0xf], 9, 0xc33707d6);  // 25
                GG(ref c, d, a, b, blockPtr[(5 * 26 + 1) & 0xf], 14, 0xf4d50d87); // 26
                GG(ref b, c, d, a, blockPtr[(5 * 27 + 1) & 0xf], 20, 0x455a14ed); // 27
                GG(ref a, b, c, d, blockPtr[(5 * 28 + 1) & 0xf], 5, 0xa9e3e905);  // 28
                GG(ref d, a, b, c, blockPtr[(5 * 29 + 1) & 0xf], 9, 0xfcefa3f8);  // 29
                GG(ref c, d, a, b, blockPtr[(5 * 30 + 1) & 0xf], 14, 0x676f02d9); // 30
                GG(ref b, c, d, a, blockPtr[(5 * 31 + 1) & 0xf], 20, 0x8d2a4c8a); // 31

                HH(ref a, b, c, d, blockPtr[(3 * 32 + 5) & 0xf], 4, 0xfffa3942);  // 32
                HH(ref d, a, b, c, blockPtr[(3 * 33 + 5) & 0xf], 11, 0x8771f681); // 33
                HH(ref c, d, a, b, blockPtr[(3 * 34 + 5) & 0xf], 16, 0x6d9d6122); // 34
                HH(ref b, c, d, a, blockPtr[(3 * 35 + 5) & 0xf], 23, 0xfde5380c); // 35
                HH(ref a, b, c, d, blockPtr[(3 * 36 + 5) & 0xf], 4, 0xa4beea44);  // 36
                HH(ref d, a, b, c, blockPtr[(3 * 37 + 5) & 0xf], 11, 0x4bdecfa9); // 37
                HH(ref c, d, a, b, blockPtr[(3 * 38 + 5) & 0xf], 16, 0xf6bb4b60); // 38
                HH(ref b, c, d, a, blockPtr[(3 * 39 + 5) & 0xf], 23, 0xbebfbc70); // 39
                HH(ref a, b, c, d, blockPtr[(3 * 40 + 5) & 0xf], 4, 0x289b7ec6);  // 40
                HH(ref d, a, b, c, blockPtr[(3 * 41 + 5) & 0xf], 11, 0xeaa127fa); // 41
                HH(ref c, d, a, b, blockPtr[(3 * 42 + 5) & 0xf], 16, 0xd4ef3085); // 42
                HH(ref b, c, d, a, blockPtr[(3 * 43 + 5) & 0xf], 23, 0x4881d05);  // 43
                HH(ref a, b, c, d, blockPtr[(3 * 44 + 5) & 0xf], 4, 0xd9d4d039);  // 44
                HH(ref d, a, b, c, blockPtr[(3 * 45 + 5) & 0xf], 11, 0xe6db99e5); // 45
                HH(ref c, d, a, b, blockPtr[(3 * 46 + 5) & 0xf], 16, 0x1fa27cf8); // 46
                HH(ref b, c, d, a, blockPtr[(3 * 47 + 5) & 0xf], 23, 0xc4ac5665); // 47

                II(ref a, b, c, d, blockPtr[(7 * 48) & 0xf], 6, 0xf4292244);      // 48
                II(ref d, a, b, c, blockPtr[(7 * 49) & 0xf], 10, 0x432aff97);     // 49
                II(ref c, d, a, b, blockPtr[(7 * 50) & 0xf], 15, 0xab9423a7);     // 50
                II(ref b, c, d, a, blockPtr[(7 * 51) & 0xf], 21, 0xfc93a039);     // 51
                II(ref a, b, c, d, blockPtr[(7 * 52) & 0xf], 6, 0x655b59c3);      // 52
                II(ref d, a, b, c, blockPtr[(7 * 53) & 0xf], 10, 0x8f0ccc92);     // 53
                II(ref c, d, a, b, blockPtr[(7 * 54) & 0xf], 15, 0xffeff47d);     // 54
                II(ref b, c, d, a, blockPtr[(7 * 55) & 0xf], 21, 0x85845dd1);     // 55
                II(ref a, b, c, d, blockPtr[(7 * 56) & 0xf], 6, 0x6fa87e4f);      // 56
                II(ref d, a, b, c, blockPtr[(7 * 57) & 0xf], 10, 0xfe2ce6e0);     // 57
                II(ref c, d, a, b, blockPtr[(7 * 58) & 0xf], 15, 0xa3014314);     // 58
                II(ref b, c, d, a, blockPtr[(7 * 59) & 0xf], 21, 0x4e0811a1);     // 59
                II(ref a, b, c, d, blockPtr[(7 * 60) & 0xf], 6, 0xf7537e82);      // 60
                II(ref d, a, b, c, blockPtr[(7 * 61) & 0xf], 10, 0xbd3af235);     // 61
                II(ref c, d, a, b, blockPtr[(7 * 62) & 0xf], 15, 0x2ad7d2bb);     // 62
                II(ref b, c, d, a, blockPtr[(7 * 63) & 0xf], 21, 0xeb86d391);     // 63

                digest->A += a;
                digest->B += b;
                digest->C += c;
                digest->D += d;
            }
        }
Example #4
0
        public static void GetDigest(byte *input, int length, Md5Digest *digest)
        {
            if (s_sinesPtr == null)
            {
                Initialize();
            }

            const int bytesPerBlock = 64;
            var       blocksCount   = (length + 8) / bytesPerBlock + 1;

            digest->A = 0x67452301;
            digest->B = 0xefcdab89;
            digest->C = 0x98badcfe;
            digest->D = 0x10325476;

            var paddingBlockData = default(Block);

            for (var blockIndex = 0; blockIndex < blocksCount; blockIndex++)
            {
                var offset   = blockIndex * bytesPerBlock;
                var blockEnd = offset + bytesPerBlock;

                uint *blockPtr;

                if (blockEnd > length)    // we're going to run out of input on this block
                {
                    if (offset >= length) // we're already totally past the input at this point - this block is just padding, and definitely the final block
                    {
                        if (offset == length)
                        {
                            // the end of input perfectly lined up with a block - so this is the start of padding
                            *(byte *)&paddingBlockData = 0x80;
                        }
                        else
                        {
                            // this is not the start of padding, so we need to clear out any data from the first padding block
                            paddingBlockData = default(Block);
                        }

                        paddingBlockData.SetOriginalLength(length);
                    }
                    else // there is still some input left to consume before we get to padding
                    {
                        var bytesRemaining = bytesPerBlock - (blockEnd - length);
                        var paddingPtr     = (byte *)&paddingBlockData;
                        Common.UnsafeMemoryCopy(&input[offset], paddingPtr, bytesRemaining);

                        // add bit
                        paddingPtr[bytesRemaining] = 0x80;

                        // check if we can add the length
                        if (bytesPerBlock - (bytesRemaining + 1) >= 8)
                        {
                            paddingBlockData.SetOriginalLength(length);
                        }
                    }

                    blockPtr = (uint *)&paddingBlockData;
                }
                else
                {
                    blockPtr = (uint *)&input[offset];
                }

                var a = digest->A;
                var b = digest->B;
                var c = digest->C;
                var d = digest->D;

                uint f, dTemp;
                int  g;

                // 0
                f     = (b & c) | (~b & d);
                g     = 0;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[0] + blockPtr[g], s_shiftsPtr[0]);
                a     = dTemp;

                // 1
                f     = (b & c) | (~b & d);
                g     = 1;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[1] + blockPtr[g], s_shiftsPtr[1]);
                a     = dTemp;

                // 2
                f     = (b & c) | (~b & d);
                g     = 2;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[2] + blockPtr[g], s_shiftsPtr[2]);
                a     = dTemp;

                // 3
                f     = (b & c) | (~b & d);
                g     = 3;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[3] + blockPtr[g], s_shiftsPtr[3]);
                a     = dTemp;

                // 4
                f     = (b & c) | (~b & d);
                g     = 4;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[4] + blockPtr[g], s_shiftsPtr[4]);
                a     = dTemp;

                // 5
                f     = (b & c) | (~b & d);
                g     = 5;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[5] + blockPtr[g], s_shiftsPtr[5]);
                a     = dTemp;

                // 6
                f     = (b & c) | (~b & d);
                g     = 6;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[6] + blockPtr[g], s_shiftsPtr[6]);
                a     = dTemp;

                // 7
                f     = (b & c) | (~b & d);
                g     = 7;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[7] + blockPtr[g], s_shiftsPtr[7]);
                a     = dTemp;

                // 8
                f     = (b & c) | (~b & d);
                g     = 8;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[8] + blockPtr[g], s_shiftsPtr[8]);
                a     = dTemp;

                // 9
                f     = (b & c) | (~b & d);
                g     = 9;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[9] + blockPtr[g], s_shiftsPtr[9]);
                a     = dTemp;

                // 10
                f     = (b & c) | (~b & d);
                g     = 10;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[10] + blockPtr[g], s_shiftsPtr[10]);
                a     = dTemp;

                // 11
                f     = (b & c) | (~b & d);
                g     = 11;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[11] + blockPtr[g], s_shiftsPtr[11]);
                a     = dTemp;

                // 12
                f     = (b & c) | (~b & d);
                g     = 12;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[12] + blockPtr[g], s_shiftsPtr[12]);
                a     = dTemp;

                // 13
                f     = (b & c) | (~b & d);
                g     = 13;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[13] + blockPtr[g], s_shiftsPtr[13]);
                a     = dTemp;

                // 14
                f     = (b & c) | (~b & d);
                g     = 14;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[14] + blockPtr[g], s_shiftsPtr[14]);
                a     = dTemp;

                // 15
                f     = (b & c) | (~b & d);
                g     = 15;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[15] + blockPtr[g], s_shiftsPtr[15]);
                a     = dTemp;

                // 16
                f     = (d & b) | (~d & c);
                g     = (5 * 16 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[16] + blockPtr[g], s_shiftsPtr[16]);
                a     = dTemp;

                // 17
                f     = (d & b) | (~d & c);
                g     = (5 * 17 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[17] + blockPtr[g], s_shiftsPtr[17]);
                a     = dTemp;

                // 18
                f     = (d & b) | (~d & c);
                g     = (5 * 18 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[18] + blockPtr[g], s_shiftsPtr[18]);
                a     = dTemp;

                // 19
                f     = (d & b) | (~d & c);
                g     = (5 * 19 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[19] + blockPtr[g], s_shiftsPtr[19]);
                a     = dTemp;

                // 20
                f     = (d & b) | (~d & c);
                g     = (5 * 20 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[20] + blockPtr[g], s_shiftsPtr[20]);
                a     = dTemp;

                // 21
                f     = (d & b) | (~d & c);
                g     = (5 * 21 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[21] + blockPtr[g], s_shiftsPtr[21]);
                a     = dTemp;

                // 22
                f     = (d & b) | (~d & c);
                g     = (5 * 22 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[22] + blockPtr[g], s_shiftsPtr[22]);
                a     = dTemp;

                // 23
                f     = (d & b) | (~d & c);
                g     = (5 * 23 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[23] + blockPtr[g], s_shiftsPtr[23]);
                a     = dTemp;

                // 24
                f     = (d & b) | (~d & c);
                g     = (5 * 24 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[24] + blockPtr[g], s_shiftsPtr[24]);
                a     = dTemp;

                // 25
                f     = (d & b) | (~d & c);
                g     = (5 * 25 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[25] + blockPtr[g], s_shiftsPtr[25]);
                a     = dTemp;

                // 26
                f     = (d & b) | (~d & c);
                g     = (5 * 26 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[26] + blockPtr[g], s_shiftsPtr[26]);
                a     = dTemp;

                // 27
                f     = (d & b) | (~d & c);
                g     = (5 * 27 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[27] + blockPtr[g], s_shiftsPtr[27]);
                a     = dTemp;

                // 28
                f     = (d & b) | (~d & c);
                g     = (5 * 28 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[28] + blockPtr[g], s_shiftsPtr[28]);
                a     = dTemp;

                // 29
                f     = (d & b) | (~d & c);
                g     = (5 * 29 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[29] + blockPtr[g], s_shiftsPtr[29]);
                a     = dTemp;

                // 30
                f     = (d & b) | (~d & c);
                g     = (5 * 30 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[30] + blockPtr[g], s_shiftsPtr[30]);
                a     = dTemp;

                // 31
                f     = (d & b) | (~d & c);
                g     = (5 * 31 + 1) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[31] + blockPtr[g], s_shiftsPtr[31]);
                a     = dTemp;

                // 32
                f     = b ^ c ^ d;
                g     = (3 * 32 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[32] + blockPtr[g], s_shiftsPtr[32]);
                a     = dTemp;

                // 33
                f     = b ^ c ^ d;
                g     = (3 * 33 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[33] + blockPtr[g], s_shiftsPtr[33]);
                a     = dTemp;

                // 34
                f     = b ^ c ^ d;
                g     = (3 * 34 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[34] + blockPtr[g], s_shiftsPtr[34]);
                a     = dTemp;

                // 35
                f     = b ^ c ^ d;
                g     = (3 * 35 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[35] + blockPtr[g], s_shiftsPtr[35]);
                a     = dTemp;

                // 36
                f     = b ^ c ^ d;
                g     = (3 * 36 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[36] + blockPtr[g], s_shiftsPtr[36]);
                a     = dTemp;

                // 37
                f     = b ^ c ^ d;
                g     = (3 * 37 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[37] + blockPtr[g], s_shiftsPtr[37]);
                a     = dTemp;

                // 38
                f     = b ^ c ^ d;
                g     = (3 * 38 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[38] + blockPtr[g], s_shiftsPtr[38]);
                a     = dTemp;

                // 39
                f     = b ^ c ^ d;
                g     = (3 * 39 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[39] + blockPtr[g], s_shiftsPtr[39]);
                a     = dTemp;

                // 40
                f     = b ^ c ^ d;
                g     = (3 * 40 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[40] + blockPtr[g], s_shiftsPtr[40]);
                a     = dTemp;

                // 41
                f     = b ^ c ^ d;
                g     = (3 * 41 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[41] + blockPtr[g], s_shiftsPtr[41]);
                a     = dTemp;

                // 42
                f     = b ^ c ^ d;
                g     = (3 * 42 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[42] + blockPtr[g], s_shiftsPtr[42]);
                a     = dTemp;

                // 43
                f     = b ^ c ^ d;
                g     = (3 * 43 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[43] + blockPtr[g], s_shiftsPtr[43]);
                a     = dTemp;

                // 44
                f     = b ^ c ^ d;
                g     = (3 * 44 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[44] + blockPtr[g], s_shiftsPtr[44]);
                a     = dTemp;

                // 45
                f     = b ^ c ^ d;
                g     = (3 * 45 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[45] + blockPtr[g], s_shiftsPtr[45]);
                a     = dTemp;

                // 46
                f     = b ^ c ^ d;
                g     = (3 * 46 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[46] + blockPtr[g], s_shiftsPtr[46]);
                a     = dTemp;

                // 47
                f     = b ^ c ^ d;
                g     = (3 * 47 + 5) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[47] + blockPtr[g], s_shiftsPtr[47]);
                a     = dTemp;

                // 48
                f     = c ^ (b | ~d);
                g     = (7 * 48) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[48] + blockPtr[g], s_shiftsPtr[48]);
                a     = dTemp;

                // 49
                f     = c ^ (b | ~d);
                g     = (7 * 49) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[49] + blockPtr[g], s_shiftsPtr[49]);
                a     = dTemp;

                // 50
                f     = c ^ (b | ~d);
                g     = (7 * 50) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[50] + blockPtr[g], s_shiftsPtr[50]);
                a     = dTemp;

                // 51
                f     = c ^ (b | ~d);
                g     = (7 * 51) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[51] + blockPtr[g], s_shiftsPtr[51]);
                a     = dTemp;

                // 52
                f     = c ^ (b | ~d);
                g     = (7 * 52) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[52] + blockPtr[g], s_shiftsPtr[52]);
                a     = dTemp;

                // 53
                f     = c ^ (b | ~d);
                g     = (7 * 53) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[53] + blockPtr[g], s_shiftsPtr[53]);
                a     = dTemp;

                // 54
                f     = c ^ (b | ~d);
                g     = (7 * 54) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[54] + blockPtr[g], s_shiftsPtr[54]);
                a     = dTemp;

                // 55
                f     = c ^ (b | ~d);
                g     = (7 * 55) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[55] + blockPtr[g], s_shiftsPtr[55]);
                a     = dTemp;

                // 56
                f     = c ^ (b | ~d);
                g     = (7 * 56) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[56] + blockPtr[g], s_shiftsPtr[56]);
                a     = dTemp;

                // 57
                f     = c ^ (b | ~d);
                g     = (7 * 57) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[57] + blockPtr[g], s_shiftsPtr[57]);
                a     = dTemp;

                // 58
                f     = c ^ (b | ~d);
                g     = (7 * 58) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[58] + blockPtr[g], s_shiftsPtr[58]);
                a     = dTemp;

                // 59
                f     = c ^ (b | ~d);
                g     = (7 * 59) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[59] + blockPtr[g], s_shiftsPtr[59]);
                a     = dTemp;

                // 60
                f     = c ^ (b | ~d);
                g     = (7 * 60) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[60] + blockPtr[g], s_shiftsPtr[60]);
                a     = dTemp;

                // 61
                f     = c ^ (b | ~d);
                g     = (7 * 61) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[61] + blockPtr[g], s_shiftsPtr[61]);
                a     = dTemp;

                // 62
                f     = c ^ (b | ~d);
                g     = (7 * 62) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[62] + blockPtr[g], s_shiftsPtr[62]);
                a     = dTemp;

                // 63
                f     = c ^ (b | ~d);
                g     = (7 * 63) % 16;
                dTemp = d;
                d     = c;
                c     = b;
                b    += LeftRotate(a + f + s_sinesPtr[63] + blockPtr[g], s_shiftsPtr[63]);
                a     = dTemp;

                digest->A += a;
                digest->B += b;
                digest->C += c;
                digest->D += d;
            }
        }
Example #5
0
        public static unsafe void GetDigest(byte *input, int length, Md5Digest *digest)
        {
            const int bytesPerBlock = 64;
            var       blocksCount   = (length + 8) / bytesPerBlock + 1;

            digest->A = 0x67452301;
            digest->B = 0xefcdab89;
            digest->C = 0x98badcfe;
            digest->D = 0x10325476;

            var paddingBlockData = default(Block);

            for (var blockIndex = 0; blockIndex < blocksCount; blockIndex++)
            {
                var offset   = blockIndex * bytesPerBlock;
                var blockEnd = offset + bytesPerBlock;

                uint *blockPtr;

                if (blockEnd > length)    // we're going to run out of input on this block
                {
                    if (offset >= length) // we're already totally past the input at this point - this block is just padding, and definitely the final block
                    {
                        if (offset == length)
                        {
                            // the end of input perfectly lined up with a block - so this is the start of padding
                            *(byte *)&paddingBlockData = 0x80;
                        }
                        else
                        {
                            // this is not the start of padding, so we need to clear out any data from the first padding block
                            paddingBlockData = default(Block);
                        }

                        paddingBlockData.SetOriginalLength(length);
                    }
                    else // there is still some input left to consume before we get to padding
                    {
                        var bytesRemaining = bytesPerBlock - (blockEnd - length);
                        var paddingPtr     = (byte *)&paddingBlockData;
                        Common.UnsafeMemoryCopy(&input[offset], paddingPtr, bytesRemaining);

                        // add bit
                        paddingPtr[bytesRemaining] = 0x80;

                        // check if we can add the length
                        if (bytesPerBlock - (bytesRemaining + 1) >= 8)
                        {
                            paddingBlockData.SetOriginalLength(length);
                        }
                    }

                    blockPtr = (uint *)&paddingBlockData;
                }
                else
                {
                    blockPtr = (uint *)&input[offset];
                }

                var a = digest->A;
                var b = digest->B;
                var c = digest->C;
                var d = digest->D;

                for (var i = 0; i < bytesPerBlock; i++)
                {
                    uint f;
                    int  g;

                    if (i < 16)
                    {
                        f = (b & c) | (~b & d);
                        g = i;
                    }
                    else if (i < 32)
                    {
                        f = (d & b) | (~d & c);
                        g = (5 * i + 1) % 16;
                    }
                    else if (i < 48)
                    {
                        f = b ^ c ^ d;
                        g = (3 * i + 5) % 16;
                    }
                    else
                    {
                        f = c ^ (b | ~d);
                        g = (7 * i) % 16;
                    }

                    var dTemp = d;
                    d = c;
                    c = b;

                    var k = s_sines[i];
                    var s = s_shifts[i];
                    var m = blockPtr[g];

                    b += LeftRotate(a + f + k + m, s);
                    a  = dTemp;
                }

                digest->A += a;
                digest->B += b;
                digest->C += c;
                digest->D += d;
            }
        }