public static byte[] MD5(byte[] data)
        {
            //MD5 formats its data in the same way SHA1 and SHA2 do.
            SHADataContext ctx = new SHADataContext(data);

            //MD5 initial hash state
            uint *state = stackalloc uint[4]
            {
                0x67452301,
                0xefcdab89,
                0x98badcfe,
                0x10325476
            };

            //MD5 schedule memory
            uint *schedule = stackalloc uint[16];

            do
            {
                //Prepare first/next block
                ctx.PrepareBlock((byte *)schedule, sizeof(uint) * 16);

                if (!BitConverter.IsLittleEndian) //If big endian, reverse data endianess
                {
                    ReverseEndianess(schedule, 16);
                }

                //Process data into hash state
                ProcessBlockMD5(state, schedule);
            }while (!ctx.Complete);

            //Hash byte order correction
            if (!BitConverter.IsLittleEndian)
            {
                //fast path removes a copy on big endian platforms

                byte[] hash = new byte[sizeof(uint) * 4];

                fixed(byte *pHash = hash)
                {
                    StateCopyReversed_MD5(state, pHash);
                }

                return(hash);
            }
            else
            {
                return(new Span <byte>(state, sizeof(uint) * 4).ToArray());
            }
        }
        public static byte[] SHA512(byte[] data)
        {
            SHADataContext ctx = new SHADataContext(data, SHADataContext.AlgorithmWordSize._64);

            ulong *state = stackalloc ulong[8]
            {
                0x6a09e667f3bcc908,
                0xbb67ae8584caa73b,
                0x3c6ef372fe94f82b,
                0xa54ff53a5f1d36f1,
                0x510e527fade682d1,
                0x9b05688c2b3e6c1f,
                0x1f83d9abfb41bd6b,
                0x5be0cd19137e2179
            };

            ulong *schedule = stackalloc ulong[80];

            do
            {
                ctx.PrepareBlock((byte *)schedule, sizeof(ulong) * 16);
                InitScheduleSHA512(schedule);
                ProcessBlockSHA512(state, schedule);
            }while (!ctx.Complete);

            if (BitConverter.IsLittleEndian)
            {
                var hash = new byte[8 * sizeof(ulong)];

                if (Avx2.IsSupported)
                {
                    Vector256 <ulong> vec = Avx2.LoadVector256(state), vec2 = Avx2.LoadVector256(state + 4);

                    Unsafe.As <byte, Vector256 <byte> >(ref hash[0]) = Avx2.Shuffle(vec.AsByte(), ReverseEndianess_64_256);
                    Unsafe.As <byte, Vector256 <byte> >(ref hash[sizeof(ulong) * 4]) = Avx2.Shuffle(vec2.AsByte(), ReverseEndianess_64_256);
                }
                else
                {
                    fixed(byte *phash = hash)
                    ReverseEndianess(state, (ulong *)phash, 8);
                }

                return(hash);
            }
            else
            {
                return(new Span <byte>(state, sizeof(ulong) * 8).ToArray());
            }
        }
示例#3
0
        public static byte[] SHA224(byte[] data)
        {
            SHADataContext ctx = new SHADataContext(data);

            uint *state = stackalloc uint[8]
            {
                0xc1059ed8,
                0x367cd507,
                0x3070dd17,
                0xf70e5939,
                0xffc00b31,
                0x68581511,
                0x64f98fa7,
                0xbefa4fa4
            };

            uint *schedule = stackalloc uint[64];

            do
            {
                ctx.PrepareBlock((byte *)schedule, sizeof(uint) * 16);
                InitScheduleSHA256(schedule);
                ProcessBlockSHA256(state, schedule);
            }while (!ctx.Complete);

            if (BitConverter.IsLittleEndian)
            {
                byte[] hash = new byte[sizeof(uint) * 7];

                fixed(byte *phash = hash)
                {
                    ReverseEndianess(state, (uint *)phash, 7);
                }

                return(hash);
            }
            else
            {
                return(new Span <byte>(state, sizeof(uint) * 7).ToArray());
            }
        }
        public static byte[] SHA384(byte[] data)
        {
            SHADataContext ctx = new SHADataContext(data, SHADataContext.AlgorithmWordSize._64);

            ulong *state = stackalloc ulong[8]
            {
                0xcbbb9d5dc1059ed8,
                0x629a292a367cd507,
                0x9159015a3070dd17,
                0x152fecd8f70e5939,
                0x67332667ffc00b31,
                0x8eb44a8768581511,
                0xdb0c2e0d64f98fa7,
                0x47b5481dbefa4fa4
            };

            ulong *schedule = stackalloc ulong[80];

            do
            {
                ctx.PrepareBlock((byte *)schedule, sizeof(ulong) * 16);
                InitScheduleSHA512(schedule);
                ProcessBlockSHA512(state, schedule);
            }while (!ctx.Complete);

            if (BitConverter.IsLittleEndian)
            {
                byte[] hash = new byte[sizeof(ulong) * 6];

                fixed(byte *pHash = hash)
                {
                    ReverseEndianess(state, (ulong *)pHash, 6);
                }

                return(hash);
            }

            return(new Span <byte>(state, sizeof(ulong) * 6).ToArray());
        }
        public static byte[] SHA1(byte[] data)
        {
            SHADataContext ctx = new SHADataContext(data);

            uint *state = stackalloc uint[5]
            {
                0x67452301,
                0xEFCDAB89,
                0x98BADCFE,
                0x10325476,
                0xC3D2E1F0
            };

            uint *schedule = stackalloc uint[80];

            do
            {
                ctx.PrepareBlock((byte *)schedule, sizeof(uint) * 16);
                InitScheduleSHA1(schedule);
                ProcessBlockSHA1(state, schedule);
            }while (!ctx.Complete);

            //Byte order correction
            if (BitConverter.IsLittleEndian)
            {
                byte[] hash = new byte[5 * sizeof(uint)];

                fixed(byte *phash = hash)
                {
                    ReverseEndianess(state, (uint *)phash, 5);
                }

                return(hash);
            }
            else
            {
                return(new Span <byte>(state, 5 * sizeof(uint)).ToArray());
            }
        }
示例#6
0
        public static byte[] SHA256(byte[] data)
        {
            SHADataContext ctx = new SHADataContext(data);

            uint *state = stackalloc uint[8]
            {
                0x6a09e667,
                0xbb67ae85,
                0x3c6ef372,
                0xa54ff53a,
                0x510e527f,
                0x9b05688c,
                0x1f83d9ab,
                0x5be0cd19
            };

            uint *schedule = stackalloc uint[64];

            do
            {
                ctx.PrepareBlock((byte *)schedule, sizeof(uint) * 16);
                InitScheduleSHA256(schedule);
                ProcessBlockSHA256(state, schedule);
            }while (!ctx.Complete);

            if (BitConverter.IsLittleEndian)
            {
                byte[] hash = new byte[sizeof(uint) * 8];

                fixed(byte *phash = hash)
                ReverseEndianess(state, (uint *)phash, 8);

                return(hash);
            }

            return(new Span <byte>(state, sizeof(uint) * 8).ToArray());
        }
        public static unsafe byte[][] MD5Parallel(byte[] data1, byte[] data2, byte[] data3, byte[] data4)
        {
            if (!Sse2.IsSupported)
            {
                throw new NotSupportedException(SSE2_NotAvailable);
            }

            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException(BigEndian_NotSupported);
            }

            const int HashSize = sizeof(uint) * 4;

            SHADataContext[] ctxArr = new SHADataContext[4]
            {
                new SHADataContext(data1),
                new SHADataContext(data2),
                new SHADataContext(data3),
                new SHADataContext(data4)
            };

            byte[][] hashes = AllocateHashs(4, HashSize);

            Vector128 <uint> *state = stackalloc Vector128 <uint>[4]
            {
                Vector128.Create(0x67452301u),
                Vector128.Create(0xefcdab89u),
                Vector128.Create(0x98badcfeu),
                Vector128.Create(0x10325476u)
            };

            bool *flags = stackalloc bool[Vector128 <uint> .Count];

            Unsafe.InitBlock(flags, 0, 4); //Assuming 4 bytes, aligned

            uint *blocksPtr = stackalloc uint[16 * Vector128 <uint> .Count];

            Vector128 <uint> *schedule = stackalloc Vector128 <uint> [16];

            int concurrentHashes = 4;

            do
            {
                for (int i = 0; i < Vector128 <uint> .Count; ++i)
                {
                    ref SHADataContext ctx = ref ctxArr[i];

                    if (!ctx.Complete)
                    {
                        ctx.PrepareBlock((byte *)(blocksPtr + i * 16), sizeof(uint) * 16);
                    }
                }

                TransformParallelSchedule(schedule, blocksPtr);

                ProcessBlocksParallelMD5(state, schedule);

                for (int i = 0; i < Vector128 <uint> .Count; ++i)
                {
                    ref SHADataContext ctx = ref ctxArr[i];

                    if (flags[i] != ctx.Complete)
                    {
                        flags[i] = ctx.Complete;

                        fixed(byte *pHash = hashes[i])
                        {
                            ExtractHashState_MD5(state, (uint *)pHash, i);
                        }

                        concurrentHashes -= 1;
                    }
                }
            }while (concurrentHashes > 2);
        public static byte[][] SHA384Parallel(byte[] data1, byte[] data2)
        {
            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException(BigEndian_NotSupported);
            }

            if (!Sse2.IsSupported)
            {
                throw new NotSupportedException(SSE2_NotAvailable);
            }

            Vector128 <ulong> *state = stackalloc Vector128 <ulong>[8]
            {
                Vector128.Create(0xcbbb9d5dc1059ed8u),
                Vector128.Create(0x629a292a367cd507u),
                Vector128.Create(0x9159015a3070dd17u),
                Vector128.Create(0x152fecd8f70e5939u),
                Vector128.Create(0x67332667ffc00b31u),
                Vector128.Create(0x8eb44a8768581511u),
                Vector128.Create(0xdb0c2e0d64f98fa7u),
                Vector128.Create(0x47b5481dbefa4fa4u)
            };

            ulong *blocks = stackalloc ulong[16 * 2];

            Vector128 <ulong> *schedule = stackalloc Vector128 <ulong> [80];

            bool *flags = stackalloc bool[Vector128 <ulong> .Count];

            Unsafe.InitBlock(flags, 0, 2);

            var contexts = new SHADataContext[2]
            {
                new SHADataContext(data1, SHADataContext.AlgorithmWordSize._64),
                new SHADataContext(data2, SHADataContext.AlgorithmWordSize._64)
            };

            byte[][] hashes = AllocateHashs(2, sizeof(ulong) * 6);

            int concurrentHashes = 2, i;

            do
            {
                for (i = 0; i < 2; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (!ctx.Complete)
                    {
                        ctx.PrepareBlock((byte *)(blocks + i * 16), sizeof(ulong) * 16);
                    }
                }

                InitScheduleSHA512Parallel(schedule, blocks);

                ProcessBlocksParallelSHA512(state, schedule);

                for (i = 0; i < 2; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (flags[i] != ctx.Complete)
                    {
                        flags[i] = ctx.Complete;

                        fixed(byte *hash = hashes[i])
                        {
                            ExtractHashState_SHA384(state, (ulong *)hash, i);
                        }

                        concurrentHashes -= 1;
                    }
                }
            }while (concurrentHashes > 1);
示例#9
0
        public static byte[][] SHA224Parallel(byte[] data1, byte[] data2, byte[] data3, byte[] data4)
        {
            if (!Sse2.IsSupported)
            {
                throw new NotSupportedException(SSE2_NotAvailable);
            }

            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException(BigEndian_NotSupported);
            }

            Vector128 <uint> *state = stackalloc Vector128 <uint>[8]
            {
                Vector128.Create(0xc1059ed8u),
                Vector128.Create(0x367cd507u),
                Vector128.Create(0x3070dd17u),
                Vector128.Create(0xf70e5939u),
                Vector128.Create(0xffc00b31u),
                Vector128.Create(0x68581511u),
                Vector128.Create(0x64f98fa7u),
                Vector128.Create(0xbefa4fa4u)
            };

            bool *flags = stackalloc bool[4];

            Unsafe.InitBlock(flags, 0, 4);

            SHADataContext[] contexts = new SHADataContext[4]
            {
                new SHADataContext(data1),
                new SHADataContext(data2),
                new SHADataContext(data3),
                new SHADataContext(data4)
            };

            uint *blocks = stackalloc uint[16 * 4];

            Vector128 <uint> *schedule = stackalloc Vector128 <uint> [64];

            byte[][] hashes = AllocateHashs(4, sizeof(uint) * 7);

            int concurrentHashes = 4, i;

            do
            {
                for (i = 0; i < 4; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (!ctx.Complete)
                    {
                        ctx.PrepareBlock((byte *)(blocks + i * 16), sizeof(uint) * 16);
                    }
                }

                InitScheduleSHA256Parallel(schedule, blocks);

                ProcessBlocksParallelSHA256(state, schedule);

                for (i = 0; i < 4; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (flags[i] != ctx.Complete)
                    {
                        flags[i] = ctx.Complete;

                        fixed(byte *pHash = hashes[i])
                        ExtractHashState_SHA224(state, (uint *)pHash, i);

                        concurrentHashes -= 1;
                    }
                }
            }while (concurrentHashes > 2);
        public static unsafe byte[][] SHA1Parallel(byte[] data1, byte[] data2, byte[] data3, byte[] data4)
        {
            if (!Sse2.IsSupported)
            {
                throw new NotSupportedException(SSE2_NotAvailable);
            }

            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException(BigEndian_NotSupported);
            }

            Vector128 <uint> *state = stackalloc Vector128 <uint>[5]
            {
                Vector128.Create(0x67452301u),
                Vector128.Create(0xEFCDAB89u),
                Vector128.Create(0x98BADCFEu),
                Vector128.Create(0x10325476u),
                Vector128.Create(0xC3D2E1F0u)
            };

            bool *flags = stackalloc bool[4];

            Unsafe.InitBlock(flags, 0, 4);

            SHADataContext[] contexts = new SHADataContext[4]
            {
                new SHADataContext(data1),
                new SHADataContext(data2),
                new SHADataContext(data3),
                new SHADataContext(data4)
            };

            uint *blocks = stackalloc uint[16 * 4];

            Vector128 <uint> *schedule = stackalloc Vector128 <uint> [80];

            byte[][] hashes = AllocateHashs(4, sizeof(uint) * 5);

            int concurrentHashes = 4, i;

            do
            {
                for (i = 0; i < 4; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (!ctx.Complete)
                    {
                        ctx.PrepareBlock((byte *)(blocks + i * 16), sizeof(uint) * 16);
                    }
                }

                InitScheduleSHA1Parallel(schedule, blocks);

                ProcessBlocksParallelSHA1(state, schedule);

                for (i = 0; i < 4; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (flags[i] != ctx.Complete)
                    {
                        flags[i] = ctx.Complete;

                        fixed(byte *pHash = hashes[i])
                        {
                            ExtractHashState_SHA1(state, (uint *)pHash, i);
                        }

                        concurrentHashes -= 1;
                    }
                }
            }while (concurrentHashes > 2);
        public static byte[][] SHA512Parallel(byte[] data1, byte[] data2)
        {
            if (!Sse2.IsSupported)
            {
                throw new NotSupportedException(SSE2_NotAvailable);
            }

            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException(BigEndian_NotSupported);
            }

            Vector128 <ulong> *state = stackalloc Vector128 <ulong>[8]
            {
                Vector128.Create(0x6a09e667f3bcc908u),
                Vector128.Create(0xbb67ae8584caa73bu),
                Vector128.Create(0x3c6ef372fe94f82bu),
                Vector128.Create(0xa54ff53a5f1d36f1u),
                Vector128.Create(0x510e527fade682d1u),
                Vector128.Create(0x9b05688c2b3e6c1fu),
                Vector128.Create(0x1f83d9abfb41bd6bu),
                Vector128.Create(0x5be0cd19137e2179u)
            };

            ulong *blocks = stackalloc ulong[16 * 2];

            Vector128 <ulong> *schedule = stackalloc Vector128 <ulong> [80];

            bool *flags = stackalloc bool[Vector128 <ulong> .Count];

            Unsafe.InitBlock(flags, 0, 2);

            SHADataContext[] contexts = new SHADataContext[2]
            {
                new SHADataContext(data1, SHADataContext.AlgorithmWordSize._64),
                new SHADataContext(data2, SHADataContext.AlgorithmWordSize._64)
            };

            byte[][] hashes = AllocateHashs(2, sizeof(ulong) * 8);

            int concurrentHashes = 2, i;

            do
            {
                for (i = 0; i < 2; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (!ctx.Complete)
                    {
                        ctx.PrepareBlock((byte *)(blocks + i * 16), sizeof(ulong) * 16);
                    }
                }

                InitScheduleSHA512Parallel(schedule, blocks);

                ProcessBlocksParallelSHA512(state, schedule);

                for (i = 0; i < 2; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (flags[i] != ctx.Complete)
                    {
                        flags[i] = ctx.Complete;

                        fixed(byte *hash = hashes[i])
                        {
                            ExtractHashState_SHA512(state, (ulong *)hash, i);
                        }

                        concurrentHashes -= 1;
                    }
                }
            }while (concurrentHashes > 1);
示例#12
0
        public static byte[][] SHA256Parallel(byte[] data1, byte[] data2, byte[] data3, byte[] data4)
        {
            if (!Sse2.IsSupported)
            {
                throw new NotSupportedException(SSE2_NotAvailable);
            }

            if (!BitConverter.IsLittleEndian)
            {
                throw new NotSupportedException(BigEndian_NotSupported);
            }

            Vector128 <uint> *state = stackalloc Vector128 <uint>[8]
            {
                Vector128.Create(0x6a09e667u),
                Vector128.Create(0xbb67ae85u),
                Vector128.Create(0x3c6ef372u),
                Vector128.Create(0xa54ff53au),
                Vector128.Create(0x510e527fu),
                Vector128.Create(0x9b05688cu),
                Vector128.Create(0x1f83d9abu),
                Vector128.Create(0x5be0cd19u)
            };

            bool *flags = stackalloc bool[4];

            Unsafe.InitBlock(flags, 0, 4);

            SHADataContext[] contexts = new SHADataContext[4]
            {
                new SHADataContext(data1),
                new SHADataContext(data2),
                new SHADataContext(data3),
                new SHADataContext(data4)
            };

            uint *blocks = stackalloc uint[16 * 4];

            Vector128 <uint> *schedule = stackalloc Vector128 <uint> [64];

            byte[][] hashes = AllocateHashs(4, sizeof(uint) * 8);

            int concurrentHashes = 4, i;

            do
            {
                for (i = 0; i < 4; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (!ctx.Complete)
                    {
                        ctx.PrepareBlock((byte *)(blocks + i * 16), sizeof(uint) * 16);
                    }
                }

                InitScheduleSHA256Parallel(schedule, blocks);

                ProcessBlocksParallelSHA256(state, schedule);

                for (i = 0; i < 4; ++i)
                {
                    ref SHADataContext ctx = ref contexts[i];

                    if (flags[i] != ctx.Complete)
                    {
                        flags[i] = ctx.Complete;

                        fixed(byte *pHash = hashes[i])
                        {
                            ExtractHashState_SHA256(state, (uint *)pHash, i);
                        }

                        concurrentHashes -= 1;
                    }
                }
            }while (concurrentHashes > 2);