SipHash
#include <Windows.h>
SIZE_T StringLengthW(_In_ LPCWSTR String)
{
LPCWSTR String2;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
UINT64 RotateToLeft64(UINT64 x, UINT64 Rotate)
{
return (x << Rotate) | (x >> (64 - Rotate));
}
PVOID CopyMemoryEx(_Inout_ PVOID Destination, _In_ CONST PVOID Source, _In_ SIZE_T Length)
{
PBYTE D = (PBYTE)Destination;
PBYTE S = (PBYTE)Source;
while (Length--)
*D++ = *S++;
return Destination;
}
VOID ImplSipRound(PUINT64 InternalState0, PUINT64 InternalState1, PUINT64 InternalState2, PUINT64 InternalState3)
{
*InternalState0 += *InternalState1;
*InternalState1 = RotateToLeft64(*InternalState1, 13);
*InternalState1 ^= *InternalState0;
*InternalState0 = RotateToLeft64(*InternalState0, 32);
*InternalState2 += *InternalState3;
*InternalState3 = RotateToLeft64(*InternalState3, 16);
*InternalState3 ^= *InternalState2;
*InternalState0 += *InternalState3;
*InternalState3 = RotateToLeft64(*InternalState3, 21);
*InternalState3 ^= *InternalState0;
*InternalState2 += *InternalState1;
*InternalState1 = RotateToLeft64(*InternalState1, 17);
*InternalState1 ^= *InternalState2;
*InternalState2 = RotateToLeft64(*InternalState2, 32);
}
UINT64 HashStringSipHashW(PBYTE Key, PVOID String, SIZE_T Length)
{
PBYTE Pointer = (PBYTE)String;
PBYTE InputEnd = Pointer + (Length & ~(SIZE_T)7);
UINT64 KeyBase = 0;
UINT64 KeyBaseOffset = 0;
UINT64 Block = 0;
CopyMemoryEx(&KeyBase, Key, 8);
CopyMemoryEx(&KeyBaseOffset, Key + 8, 8);
UINT64 InternalState0 = 0x736f6d6570736575ULL ^ KeyBase;
UINT64 InternalState1 = 0x646f72616e646f6dULL ^ KeyBaseOffset;
UINT64 InternalState2 = 0x6c7967656e657261ULL ^ KeyBase;
UINT64 InternalState3 = 0x7465646279746573ULL ^ KeyBaseOffset;
for (; Pointer != InputEnd; Pointer += 8)
{
UINT64 MixObject = 0;
CopyMemoryEx(&MixObject, Pointer, 8);
InternalState3 ^= MixObject;
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
InternalState0 ^= MixObject;
}
Block = (UINT64)Length << 56;
switch (Length & 7)
{
case 7: Block |= (UINT64)Pointer[6] << 48;
case 6: Block |= (UINT64)Pointer[5] << 40;
case 5: Block |= (UINT64)Pointer[4] << 32;
case 4: Block |= (UINT64)Pointer[3] << 24;
case 3: Block |= (UINT64)Pointer[2] << 16;
case 2: Block |= (UINT64)Pointer[1] << 8;
case 1: Block |= (UINT64)Pointer[0];
default: break;
}
InternalState3 ^= Block;
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
InternalState0 ^= Block;
InternalState2 ^= 0xff;
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
ImplSipRound(&InternalState0, &InternalState1, &InternalState2, &InternalState3);
return (InternalState0 & InternalState1) ^ (InternalState2 ^ InternalState3);
}
INT main(VOID)
{
WCHAR StringHashExample[] = L"Hash This String";
BYTE Key[16] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
UINT64 Hash = 0;
Hash = HashStringSipHashW(Key, StringHashExample, (StringLengthW(StringHashExample) * sizeof(WCHAR)));
return ERROR_SUCCESS;
}Last updated