diff --git a/dotnet/TrustPilotChallenge.sln b/dotnet/TrustPilotChallenge.sln
index a93fe41..2be655e 100644
--- a/dotnet/TrustPilotChallenge.sln
+++ b/dotnet/TrustPilotChallenge.sln
@@ -1,20 +1,45 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.24720.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WhiteRabbit", "WhiteRabbit\WhiteRabbit.csproj", "{3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WhiteRabbit.UnmanagedBridge", "WhiteRabbit.UnmanagedBridge\WhiteRabbit.UnmanagedBridge.vcxproj", "{039F03A0-7E8F-415D-8180-969D24479B44}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Debug|x64.Build.0 = Debug|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Debug|x86.Build.0 = Debug|Any CPU
{3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Release|x64.ActiveCfg = Release|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Release|x64.Build.0 = Release|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Release|x86.ActiveCfg = Release|Any CPU
+ {3A4E69F0-7A8E-4B92-BA02-A231D75CB3E4}.Release|x86.Build.0 = Release|Any CPU
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Debug|x64.ActiveCfg = Debug|x64
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Debug|x64.Build.0 = Debug|x64
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Debug|x86.ActiveCfg = Debug|Win32
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Debug|x86.Build.0 = Debug|Win32
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Release|Any CPU.ActiveCfg = Release|x64
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Release|Any CPU.Build.0 = Release|x64
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Release|x64.ActiveCfg = Release|x64
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Release|x64.Build.0 = Release|x64
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Release|x86.ActiveCfg = Release|Win32
+ {039F03A0-7E8F-415D-8180-969D24479B44}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/AssemblyInfo.cpp b/dotnet/WhiteRabbit.UnmanagedBridge/AssemblyInfo.cpp
new file mode 100644
index 0000000..51c754f
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/AssemblyInfo.cpp
@@ -0,0 +1,38 @@
+#include "stdafx.h"
+
+using namespace System;
+using namespace System::Reflection;
+using namespace System::Runtime::CompilerServices;
+using namespace System::Runtime::InteropServices;
+using namespace System::Security::Permissions;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly:AssemblyTitleAttribute(L"WhiteRabbitUnmanagedBridge")];
+[assembly:AssemblyDescriptionAttribute(L"")];
+[assembly:AssemblyConfigurationAttribute(L"")];
+[assembly:AssemblyCompanyAttribute(L"")];
+[assembly:AssemblyProductAttribute(L"WhiteRabbitUnmanagedBridge")];
+[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2017")];
+[assembly:AssemblyTrademarkAttribute(L"")];
+[assembly:AssemblyCultureAttribute(L"")];
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the value or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly:AssemblyVersionAttribute("1.0.*")];
+
+[assembly:ComVisible(false)];
+
+[assembly:CLSCompliantAttribute(true)];
\ No newline at end of file
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/Stdafx.cpp b/dotnet/WhiteRabbit.UnmanagedBridge/Stdafx.cpp
new file mode 100644
index 0000000..12c5cdb
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/Stdafx.cpp
@@ -0,0 +1,5 @@
+// stdafx.cpp : source file that includes just the standard includes
+// WhiteRabbit.Unmanaged.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/Stdafx.h b/dotnet/WhiteRabbit.UnmanagedBridge/Stdafx.h
new file mode 100644
index 0000000..3cc4c24
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/Stdafx.h
@@ -0,0 +1,7 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.cpp b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.cpp
new file mode 100644
index 0000000..a35acb6
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.cpp
@@ -0,0 +1,11 @@
+// This is the main DLL file.
+
+#include "stdafx.h"
+
+#include "WhiteRabbit.UnmanagedBridge.h"
+#include "md5.h"
+
+void WhiteRabbitUnmanagedBridge::MD5Unmanaged::ComputeMD5(unsigned int * input, unsigned int* output)
+{
+ md5(input, output);
+}
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.h b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.h
new file mode 100644
index 0000000..f0acb8f
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.h
@@ -0,0 +1,14 @@
+// WhiteRabbit.Unmanaged.h
+
+#pragma once
+
+using namespace System;
+
+namespace WhiteRabbitUnmanagedBridge {
+
+ public ref class MD5Unmanaged
+ {
+ public:
+ static void ComputeMD5(unsigned int* input, unsigned int* output);
+ };
+}
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.vcxproj b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.vcxproj
new file mode 100644
index 0000000..890e2d0
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.vcxproj
@@ -0,0 +1,153 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {039F03A0-7E8F-415D-8180-969D24479B44}
+ v4.5
+ ManagedCProj
+ WhiteRabbitUnmanagedBridge
+ 8.1
+
+
+
+ DynamicLibrary
+ true
+ v140
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v140
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;%(PreprocessorDefinitions)
+ Use
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ _DEBUG;%(PreprocessorDefinitions)
+ Use
+
+
+
+
+
+
+
+ Level3
+ WIN32;NDEBUG;%(PreprocessorDefinitions)
+ Use
+
+
+
+
+
+
+
+ Level3
+ NDEBUG;%(PreprocessorDefinitions)
+ Use
+ Full
+ AnySuitable
+ true
+ Speed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.vcxproj.filters b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.vcxproj.filters
new file mode 100644
index 0000000..a9ce610
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.vcxproj.filters
@@ -0,0 +1,41 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/md5.cpp b/dotnet/WhiteRabbit.UnmanagedBridge/md5.cpp
new file mode 100644
index 0000000..5a0a17e
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/md5.cpp
@@ -0,0 +1,108 @@
+#include "stdafx.h"
+
+#include "md5.h"
+
+#pragma unmanaged
+
+inline unsigned int Blend(unsigned int a, unsigned int b, unsigned int x)
+{
+ return (x & b) | (~x & a);
+}
+
+inline unsigned int Xor(unsigned int a, unsigned int b, unsigned int c)
+{
+ return a ^ b ^ c;
+}
+
+inline unsigned int I(unsigned int a, unsigned int b, unsigned int c)
+{
+ return a ^ (b | ~c);
+}
+
+inline unsigned int LeftRotate(unsigned int x, int left)
+{
+ return (x << left) | (x >> (32 - left));
+}
+
+void md5(unsigned int * input, unsigned int* output)
+{
+
+ unsigned int a = 0x67452301;
+ unsigned int b = 0xefcdab89;
+ unsigned int c = 0x98badcfe;
+ unsigned int d = 0x10325476;
+
+ a = b + LeftRotate(0xd76aa478 + a + Blend(d, c, b) + input[0], 7);
+ d = a + LeftRotate(0xe8c7b756 + d + Blend(c, b, a) + input[1], 12);
+ c = d + LeftRotate(0x242070db + c + Blend(b, a, d) + input[2], 17);
+ b = c + LeftRotate(0xc1bdceee + b + Blend(a, d, c) + input[3], 22);
+ a = b + LeftRotate(0xf57c0faf + a + Blend(d, c, b) + input[4], 7);
+ d = a + LeftRotate(0x4787c62a + d + Blend(c, b, a) + input[5], 12);
+ c = d + LeftRotate(0xa8304613 + c + Blend(b, a, d) + input[6], 17);
+ b = c + LeftRotate(0xfd469501 + b + Blend(a, d, c), 22);
+ a = b + LeftRotate(0x698098d8 + a + Blend(d, c, b), 7);
+ d = a + LeftRotate(0x8b44f7af + d + Blend(c, b, a), 12);
+ c = d + LeftRotate(0xffff5bb1 + c + Blend(b, a, d), 17);
+ b = c + LeftRotate(0x895cd7be + b + Blend(a, d, c), 22);
+ a = b + LeftRotate(0x6b901122 + a + Blend(d, c, b), 7);
+ d = a + LeftRotate(0xfd987193 + d + Blend(c, b, a), 12);
+ c = d + LeftRotate(0xa679438e + c + Blend(b, a, d) + input[7], 17);
+ b = c + LeftRotate(0x49b40821 + b + Blend(a, d, c), 22);
+
+ a = b + LeftRotate(0xf61e2562 + a + Blend(c, b, d) + input[1], 5);
+ d = a + LeftRotate(0xc040b340 + d + Blend(b, a, c) + input[6], 9);
+ c = d + LeftRotate(0x265e5a51 + c + Blend(a, d, b), 14);
+ b = c + LeftRotate(0xe9b6c7aa + b + Blend(d, c, a) + input[0], 20);
+ a = b + LeftRotate(0xd62f105d + a + Blend(c, b, d) + input[5], 5);
+ d = a + LeftRotate(0x02441453 + d + Blend(b, a, c), 9);
+ c = d + LeftRotate(0xd8a1e681 + c + Blend(a, d, b), 14);
+ b = c + LeftRotate(0xe7d3fbc8 + b + Blend(d, c, a) + input[4], 20);
+ a = b + LeftRotate(0x21e1cde6 + a + Blend(c, b, d), 5);
+ d = a + LeftRotate(0xc33707d6 + d + Blend(b, a, c) + input[7], 9);
+ c = d + LeftRotate(0xf4d50d87 + c + Blend(a, d, b) + input[3], 14);
+ b = c + LeftRotate(0x455a14ed + b + Blend(d, c, a), 20);
+ a = b + LeftRotate(0xa9e3e905 + a + Blend(c, b, d), 5);
+ d = a + LeftRotate(0xfcefa3f8 + d + Blend(b, a, c) + input[2], 9);
+ c = d + LeftRotate(0x676f02d9 + c + Blend(a, d, b), 14);
+ b = c + LeftRotate(0x8d2a4c8a + b + Blend(d, c, a), 20);
+
+ a = b + LeftRotate(0xfffa3942 + a + Xor(b, c, d) + input[5], 4);
+ d = a + LeftRotate(0x8771f681 + d + Xor(a, b, c), 11);
+ c = d + LeftRotate(0x6d9d6122 + c + Xor(d, a, b), 16);
+ b = c + LeftRotate(0xfde5380c + b + Xor(c, d, a) + input[7], 23);
+ a = b + LeftRotate(0xa4beea44 + a + Xor(b, c, d) + input[1], 4);
+ d = a + LeftRotate(0x4bdecfa9 + d + Xor(a, b, c) + input[4], 11);
+ c = d + LeftRotate(0xf6bb4b60 + c + Xor(d, a, b), 16);
+ b = c + LeftRotate(0xbebfbc70 + b + Xor(c, d, a), 23);
+ a = b + LeftRotate(0x289b7ec6 + a + Xor(b, c, d), 4);
+ d = a + LeftRotate(0xeaa127fa + d + Xor(a, b, c) + input[0], 11);
+ c = d + LeftRotate(0xd4ef3085 + c + Xor(d, a, b) + input[3], 16);
+ b = c + LeftRotate(0x04881d05 + b + Xor(c, d, a) + input[6], 23);
+ a = b + LeftRotate(0xd9d4d039 + a + Xor(b, c, d), 4);
+ d = a + LeftRotate(0xe6db99e5 + d + Xor(a, b, c), 11);
+ c = d + LeftRotate(0x1fa27cf8 + c + Xor(d, a, b), 16);
+ b = c + LeftRotate(0xc4ac5665 + b + Xor(c, d, a) + input[2], 23);
+
+ a = b + LeftRotate(0xf4292244 + a + I(c, b, d) + input[0], 6);
+ d = a + LeftRotate(0x432aff97 + d + I(b, a, c), 10);
+ c = d + LeftRotate(0xab9423a7 + c + I(a, d, b) + input[7], 15);
+ b = c + LeftRotate(0xfc93a039 + b + I(d, c, a) + input[5], 21);
+ a = b + LeftRotate(0x655b59c3 + a + I(c, b, d), 6);
+ d = a + LeftRotate(0x8f0ccc92 + d + I(b, a, c) + input[3], 10);
+ c = d + LeftRotate(0xffeff47d + c + I(a, d, b), 15);
+ b = c + LeftRotate(0x85845dd1 + b + I(d, c, a) + input[1], 21);
+ a = b + LeftRotate(0x6fa87e4f + a + I(c, b, d), 6);
+ d = a + LeftRotate(0xfe2ce6e0 + d + I(b, a, c), 10);
+ c = d + LeftRotate(0xa3014314 + c + I(a, d, b) + input[6], 15);
+ b = c + LeftRotate(0x4e0811a1 + b + I(d, c, a), 21);
+ a = b + LeftRotate(0xf7537e82 + a + I(c, b, d) + input[4], 6);
+ d = a + LeftRotate(0xbd3af235 + d + I(b, a, c), 10);
+ c = d + LeftRotate(0x2ad7d2bb + c + I(a, d, b) + input[2], 15);
+ b = c + LeftRotate(0xeb86d391 + b + I(d, c, a), 21);
+
+ output[0] = 0x67452301 + a;
+ output[1] = 0xefcdab89 + b;
+ output[2] = 0x98badcfe + c;
+ output[3] = 0x10325476 + d;
+}
+#pragma managed
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/md5.h b/dotnet/WhiteRabbit.UnmanagedBridge/md5.h
new file mode 100644
index 0000000..737b9dc
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/md5.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void md5(unsigned int* input, unsigned int* output);
diff --git a/dotnet/WhiteRabbit.UnmanagedBridge/resource.h b/dotnet/WhiteRabbit.UnmanagedBridge/resource.h
new file mode 100644
index 0000000..d5ac7c4
--- /dev/null
+++ b/dotnet/WhiteRabbit.UnmanagedBridge/resource.h
@@ -0,0 +1,3 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by app.rc
diff --git a/dotnet/WhiteRabbit/MD5Digest.cs b/dotnet/WhiteRabbit/MD5Digest.cs
index 6100ad6..d8e05d2 100644
--- a/dotnet/WhiteRabbit/MD5Digest.cs
+++ b/dotnet/WhiteRabbit/MD5Digest.cs
@@ -1,4 +1,6 @@
-using System.Runtime.CompilerServices;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using WhiteRabbitUnmanagedBridge;
namespace WhiteRabbit
{
@@ -12,112 +14,16 @@ namespace WhiteRabbit
internal static class MD5Digest
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe uint[] Compute(Phrase input)
+ public static unsafe Vector Compute(Phrase input)
{
- uint a = 0x67452301;
- uint b = 0xefcdab89;
- uint c = 0x98badcfe;
- uint d = 0x10325476;
-
- a = b + LeftRotate(0xd76aa478 + a + Blend(d, c, b) + input.Buffer[0], 7);
- d = a + LeftRotate(0xe8c7b756 + d + Blend(c, b, a) + input.Buffer[1], 12);
- c = d + LeftRotate(0x242070db + c + Blend(b, a, d) + input.Buffer[2], 17);
- b = c + LeftRotate(0xc1bdceee + b + Blend(a, d, c) + input.Buffer[3], 22);
- a = b + LeftRotate(0xf57c0faf + a + Blend(d, c, b) + input.Buffer[4], 7);
- d = a + LeftRotate(0x4787c62a + d + Blend(c, b, a) + input.Buffer[5], 12);
- c = d + LeftRotate(0xa8304613 + c + Blend(b, a, d) + input.Buffer[6], 17);
- b = c + LeftRotate(0xfd469501 + b + Blend(a, d, c), 22);
- a = b + LeftRotate(0x698098d8 + a + Blend(d, c, b), 7);
- d = a + LeftRotate(0x8b44f7af + d + Blend(c, b, a), 12);
- c = d + LeftRotate(0xffff5bb1 + c + Blend(b, a, d), 17);
- b = c + LeftRotate(0x895cd7be + b + Blend(a, d, c), 22);
- a = b + LeftRotate(0x6b901122 + a + Blend(d, c, b), 7);
- d = a + LeftRotate(0xfd987193 + d + Blend(c, b, a), 12);
- c = d + LeftRotate(0xa679438e + c + Blend(b, a, d) + input.Buffer[7], 17);
- b = c + LeftRotate(0x49b40821 + b + Blend(a, d, c), 22);
-
- a = b + LeftRotate(0xf61e2562 + a + Blend(c, b, d) + input.Buffer[1], 5);
- d = a + LeftRotate(0xc040b340 + d + Blend(b, a, c) + input.Buffer[6], 9);
- c = d + LeftRotate(0x265e5a51 + c + Blend(a, d, b), 14);
- b = c + LeftRotate(0xe9b6c7aa + b + Blend(d, c, a) + input.Buffer[0], 20);
- a = b + LeftRotate(0xd62f105d + a + Blend(c, b, d) + input.Buffer[5], 5);
- d = a + LeftRotate(0x02441453 + d + Blend(b, a, c), 9);
- c = d + LeftRotate(0xd8a1e681 + c + Blend(a, d, b), 14);
- b = c + LeftRotate(0xe7d3fbc8 + b + Blend(d, c, a) + input.Buffer[4], 20);
- a = b + LeftRotate(0x21e1cde6 + a + Blend(c, b, d), 5);
- d = a + LeftRotate(0xc33707d6 + d + Blend(b, a, c) + input.Buffer[7], 9);
- c = d + LeftRotate(0xf4d50d87 + c + Blend(a, d, b) + input.Buffer[3], 14);
- b = c + LeftRotate(0x455a14ed + b + Blend(d, c, a), 20);
- a = b + LeftRotate(0xa9e3e905 + a + Blend(c, b, d), 5);
- d = a + LeftRotate(0xfcefa3f8 + d + Blend(b, a, c) + input.Buffer[2], 9);
- c = d + LeftRotate(0x676f02d9 + c + Blend(a, d, b), 14);
- b = c + LeftRotate(0x8d2a4c8a + b + Blend(d, c, a), 20);
-
- a = b + LeftRotate(0xfffa3942 + a + Xor(b, c, d) + input.Buffer[5], 4);
- d = a + LeftRotate(0x8771f681 + d + Xor(a, b, c), 11);
- c = d + LeftRotate(0x6d9d6122 + c + Xor(d, a, b), 16);
- b = c + LeftRotate(0xfde5380c + b + Xor(c, d, a) + input.Buffer[7], 23);
- a = b + LeftRotate(0xa4beea44 + a + Xor(b, c, d) + input.Buffer[1], 4);
- d = a + LeftRotate(0x4bdecfa9 + d + Xor(a, b, c) + input.Buffer[4], 11);
- c = d + LeftRotate(0xf6bb4b60 + c + Xor(d, a, b), 16);
- b = c + LeftRotate(0xbebfbc70 + b + Xor(c, d, a), 23);
- a = b + LeftRotate(0x289b7ec6 + a + Xor(b, c, d), 4);
- d = a + LeftRotate(0xeaa127fa + d + Xor(a, b, c) + input.Buffer[0], 11);
- c = d + LeftRotate(0xd4ef3085 + c + Xor(d, a, b) + input.Buffer[3], 16);
- b = c + LeftRotate(0x04881d05 + b + Xor(c, d, a) + input.Buffer[6], 23);
- a = b + LeftRotate(0xd9d4d039 + a + Xor(b, c, d), 4);
- d = a + LeftRotate(0xe6db99e5 + d + Xor(a, b, c), 11);
- c = d + LeftRotate(0x1fa27cf8 + c + Xor(d, a, b), 16);
- b = c + LeftRotate(0xc4ac5665 + b + Xor(c, d, a) + input.Buffer[2], 23);
-
- a = b + LeftRotate(0xf4292244 + a + I(c, b, d) + input.Buffer[0], 6);
- d = a + LeftRotate(0x432aff97 + d + I(b, a, c), 10);
- c = d + LeftRotate(0xab9423a7 + c + I(a, d, b) + input.Buffer[7], 15);
- b = c + LeftRotate(0xfc93a039 + b + I(d, c, a) + input.Buffer[5], 21);
- a = b + LeftRotate(0x655b59c3 + a + I(c, b, d), 6);
- d = a + LeftRotate(0x8f0ccc92 + d + I(b, a, c) + input.Buffer[3], 10);
- c = d + LeftRotate(0xffeff47d + c + I(a, d, b), 15);
- b = c + LeftRotate(0x85845dd1 + b + I(d, c, a) + input.Buffer[1], 21);
- a = b + LeftRotate(0x6fa87e4f + a + I(c, b, d), 6);
- d = a + LeftRotate(0xfe2ce6e0 + d + I(b, a, c), 10);
- c = d + LeftRotate(0xa3014314 + c + I(a, d, b) + input.Buffer[6], 15);
- b = c + LeftRotate(0x4e0811a1 + b + I(d, c, a), 21);
- a = b + LeftRotate(0xf7537e82 + a + I(c, b, d) + input.Buffer[4], 6);
- d = a + LeftRotate(0xbd3af235 + d + I(b, a, c), 10);
- c = d + LeftRotate(0x2ad7d2bb + c + I(a, d, b) + input.Buffer[2], 15);
- b = c + LeftRotate(0xeb86d391 + b + I(d, c, a), 21);
-
- return new[]
- {
- 0x67452301 + a,
- 0xefcdab89 + b,
- 0x98badcfe + c,
- 0x10325476 + d,
- };
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static uint Blend(uint a, uint b, uint x)
- {
- return (x & b) | (~x & a);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static uint Xor(uint a, uint b, uint c)
- {
- return a ^ b ^ c;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static uint I(uint a, uint b, uint c)
- {
- return a ^ (b | ~c);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static uint LeftRotate(uint x, int left)
- {
- return (x << left) | (x >> 32 - left);
+ var result = stackalloc uint[4];
+ MD5Unmanaged.ComputeMD5(input.Buffer, result);
+ return new Vector(new[] {
+ result[0],
+ result[1],
+ result[2],
+ result[3],
+ });
}
}
}
diff --git a/dotnet/WhiteRabbit/Program.cs b/dotnet/WhiteRabbit/Program.cs
index 493d45a..8b9178f 100644
--- a/dotnet/WhiteRabbit/Program.cs
+++ b/dotnet/WhiteRabbit/Program.cs
@@ -74,7 +74,7 @@
sourceChars == ToOrderedChars(ToString(phraseBytes)),
$"StringsProcessor produced incorrect anagram: {ToString(phraseBytes)}");
- var hashVector = ComputeHashVector(phraseBytes);
+ var hashVector = MD5Digest.Compute(phraseBytes);
if (Array.IndexOf(expectedHashesAsVectors, hashVector) >= 0)
{
var phrase = ToString(phraseBytes);
@@ -117,12 +117,6 @@
.ToArray();
}
- // Bouncy Castle is used instead of standard .NET methods for performance reasons
- private static Vector ComputeHashVector(Phrase input)
- {
- return new Vector(MD5Digest.Compute(input));
- }
-
private static string VectorToHexadecimalString(Vector hash)
{
var components = Enumerable.Range(0, 4)
diff --git a/dotnet/WhiteRabbit/WhiteRabbit.csproj b/dotnet/WhiteRabbit/WhiteRabbit.csproj
index 39ab4e4..1592db4 100644
--- a/dotnet/WhiteRabbit/WhiteRabbit.csproj
+++ b/dotnet/WhiteRabbit/WhiteRabbit.csproj
@@ -27,7 +27,7 @@
false
- AnyCPU
+ x64pdbonlytruebin\Release\
@@ -73,6 +73,12 @@
+
+
+ {039f03a0-7e8f-415d-8180-969d24479b44}
+ WhiteRabbit.UnmanagedBridge
+
+