Skip to content

XXHash64/32 incorrect one-shot implementation #61878

Description

@Tornhoof

tl;dr: I upgraded one of my apps to .NET 6 and .NET 6 ships their own xxhash64 implementation, which is great. But the output was not consistent with my previous implementation. (beside mine not outputting bigendian, but that's a spec thingie).

This should be >=, you're not hashing all available data in the bulk/stride block.

Funny thing, the incremental version is correct:

Looking through the test cases, I see cases which should test boundaries, but only like 33 and 63, but not testing the power of two case and I don't see any test case (maybe I missed those, the tests are slightly convoluted for these algorithms) which compare one-shot with incremental.

The same problem is in XxHash32.

Repro:

// See https://aka.ms/new-console-template for more information

using System.Security.Cryptography;

for (int i = 127; i <= 129; i++)
{
	Console.WriteLine("Bytes-Length: {0}", i);
	var bytes = new byte[i];
	RandomNumberGenerator.Fill(bytes);

	var h = new System.IO.Hashing.XxHash64();
	h.Append(bytes);
	Console.WriteLine("System.IO.Hashing.XxHash64 Incremental: {0:X}", BitConverter.ToUInt64(h.GetHashAndReset()));

	var netOutput = System.IO.Hashing.XxHash64.Hash(bytes);
	Console.WriteLine("System.IO.Hashing.XxHash64: {0:X}", BitConverter.ToUInt64(netOutput));

	var h2 = new System.IO.Hashing.XxHash32();
	h2.Append(bytes);
	Console.WriteLine("System.IO.Hashing.XxHash32 Incremental: {0:X}", BitConverter.ToUInt32(h2.GetHashAndReset()));

	var netOutput2 = System.IO.Hashing.XxHash32.Hash(bytes);
	Console.WriteLine("System.IO.Hashing.XxHash32: {0:X}", BitConverter.ToUInt32(netOutput2));
}

Output is:

Bytes-Length: 127
System.IO.Hashing.XxHash64 Incremental: DAF756640FB36470
System.IO.Hashing.XxHash64: DAF756640FB36470
System.IO.Hashing.XxHash32 Incremental: 582BE2A5
System.IO.Hashing.XxHash32: 582BE2A5
Bytes-Length: 128
System.IO.Hashing.XxHash64 Incremental: 3E389AA2FCAFBF14
System.IO.Hashing.XxHash64: F3F710BA03289AD5
System.IO.Hashing.XxHash32 Incremental: 26D01A09
System.IO.Hashing.XxHash32: B643E2D7
Bytes-Length: 129
System.IO.Hashing.XxHash64 Incremental: 6C6BA559540903BF
System.IO.Hashing.XxHash64: 6C6BA559540903BF
System.IO.Hashing.XxHash32 Incremental: E2B400A0
System.IO.Hashing.XxHash32: E2B400A0

(note: I don't like the new multi part entry bug template, it is not possible to prepare the report in an external editor anymore or even back it up to an editor, which I usually do, so I don't accidentially lose the content when I close my browser).

@bartonjs might be of interest for you.

I'll throw up a PR to fix this, if I'll understand the test cases.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions