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()); } }
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()); } }
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);
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);
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);