# SipHash

```cpp
#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;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://malwaresourcecode.com/home/string-hashing/siphash.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
