public void ValidationTest(String hashName, UInt32 expectedValue) { Func <UInt32, Hash> hashInitializer = s_TestCases.Single(x => x.HashName == hashName).HashInitializer; Hash hash0 = hashInitializer(0u); Int32 hashBytes = hash0.Length / 8; Byte[] buffer = new Byte[256]; Byte[] bufferFinal = new Byte[hashBytes * 256]; for (Int32 i = 0; i < 256; ++i) { buffer[i] = (Byte)i; Hash hashi = hashInitializer((UInt32)(256 - i)); Byte[] hi = hashi.ComputeHash(buffer, 0, i); UnsafeBuffer.BlockCopy(hi, 0, bufferFinal, i * hashBytes, hashBytes); } Byte[] h0 = hash0.ComputeHash(bufferFinal); UInt32 actualValue = (UInt32)((h0[0] << 0) | (h0[1] << 8) | (h0[2] << 16) | (h0[3] << 24)); m_Output.WriteLine($"EXPECTED={expectedValue}"); m_Output.WriteLine($"ACTUAL={actualValue}"); Assert.Equal(expectedValue, actualValue); }
public void CollisionTest(String hashIdentifier) { ReadOnlyCollection <String> words = m_TestsFixture.Words; Hash hash = m_TestsFixture.CreateHash(hashIdentifier); Int32 hashBytes = hash.Length / 8; Byte filler = Convert.ToByte('!'); List <Byte[]> hashes = new List <Byte[]>(words.Count * 5); for (Int32 i = 0; i < words.Count; ++i) { Byte[] lineBytes = Encoding.UTF8.GetBytes(words[i]); Int32 lineBytesLength = lineBytes.Length; Byte[] buffer = new Byte[lineBytes.Length + 5]; Utilities.FillBuffer(buffer, filler); UnsafeBuffer.BlockCopy(lineBytes, 0, buffer, 0, lineBytes.Length); for (Int32 j = 0; j <= 5; ++j) { hashes.Add(hash.ComputeHash(buffer, 0, lineBytesLength + j)); } } Assert.False(Utilities.CollisionsThresholdExceeded(hashes, hashBytes)); }
public void CollisionTest(String hashName) { Int32 wordsCount = m_Fixture.Words.Count(); Assert.False(wordsCount == 0, "Fixture Words Empty"); Func <UInt32, Hash> hashInitializer = s_TestCases.Single(x => x.HashName == hashName).HashInitializer; Hash hash = hashInitializer((UInt32)((new Random()).Next())); Int32 hashBytes = hash.Length / 8; Byte filler = Convert.ToByte('!'); List <Byte[]> hashes = new List <Byte[]>(wordsCount * 5); foreach (String word in m_Fixture.Words) { Byte[] lineBytes = Encoding.UTF8.GetBytes(word); Int32 lineBytesLength = lineBytes.Length; Byte[] buffer = new Byte[lineBytes.Length + 5]; Utilities.FillBuffer(buffer, filler); UnsafeBuffer.BlockCopy(lineBytes, 0, buffer, 0, lineBytes.Length); for (Int32 j = 0; j <= 5; ++j) { hashes.Add(hash.ComputeHash(buffer, 0, lineBytesLength + j)); } } Boolean cte = Utilities.CollisionsThresholdExceeded(hashes, hashBytes); Assert.False(cte, "Collisions Threshold Exceeded"); }
public void Copy_different_blocks() { // Arrange byte[] src = new byte[100]; byte[] dst = new byte[100]; int[] counts = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 65, 66, 96, 99 }; var rand = new Random(42); rand.NextBytes(src); // Act, Assert foreach (int count in counts) { UnsafeBuffer.BlockCopy(src, 0, dst, 0, count); for (int i = 0; i < count; i++) { Assert.Equal(src[i], dst[i]); } } }
/// <summary> /// Compute xxHash for the stream /// </summary> /// <param name="stream">The stream of data</param> /// <param name="bufferSize">The buffer size</param> /// <param name="seed">The seed number</param> /// <returns>The hash</returns> public static ulong ComputeHash(Stream stream, int bufferSize = 8192, ulong seed = 0) { Debug.Assert(stream != null); Debug.Assert(bufferSize > 32); // Optimizing memory allocation byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize + 32); int readBytes; int offset = 0; long length = 0; // Prepare the seed vector ulong v1 = seed + p1 + p2; ulong v2 = seed + p2; ulong v3 = seed + 0; ulong v4 = seed - p1; try { // Read flow of bytes while ((readBytes = stream.Read(buffer, offset, bufferSize)) > 0) { length = length + readBytes; offset = offset + readBytes; if (offset < 32) { continue; } int r = offset % 32; // remain int l = offset - r; // length // Process the next chunk UnsafeAlign(buffer, l, ref v1, ref v2, ref v3, ref v4); // Put remaining bytes to buffer UnsafeBuffer.BlockCopy(buffer, l, buffer, 0, r); offset = r; } // Process the final chunk ulong h64 = UnsafeFinal(buffer, offset, ref v1, ref v2, ref v3, ref v4, length, seed); return(h64); } finally { // Free memory ArrayPool <byte> .Shared.Return(buffer); } }
public void Test(UInt32 seed, Int32?sourceLegth, Int32 sourceOffset, Int32?destinationLength, Int32 destinationOffset, Int32 count, Object expectedResult) { Byte[] source; if (sourceLegth.HasValue) { source = new Byte[sourceLegth.Value]; RandomXorShift random = new RandomXorShift(seed); random.NextBytes(source); } else { source = null; } Byte[] destination = destinationLength.HasValue ? new Byte[destinationLength.Value] : null; Object actualResult; try { UnsafeBuffer.BlockCopy(source, sourceOffset, destination, destinationOffset, count); actualResult = destination; } catch (Exception e) { actualResult = e.GetType(); } if (expectedResult is Byte[] expectedBytes) { m_Output.WriteLine($"EXPECTED={{ {String.Join(", ", expectedBytes.Select(x => x.ToString()))} }}"); } else { Type expectedType = (Type)expectedResult; m_Output.WriteLine($"EXPECTED={((expectedType == null) ? String.Empty : expectedType.Name)}"); } if (actualResult is Byte[] actualBytes) { m_Output.WriteLine($"ACTUAL={{ {String.Join(", ", actualBytes.Select(x => x.ToString()))} }}"); } else { Type actualType = (Type)actualResult; m_Output.WriteLine($"ACTUAL={((actualType == null) ? String.Empty : actualType.Name)}"); } Assert.Equal(expectedResult, actualResult); }
private static UInt64 DifferentialTestRecursion(List <Byte[]> diffs, Hash hash, Int32 keysBytes, Byte[] k1, Byte[] k2, Int32 hashBytes, Byte[] h1, Byte[] h2, Int32 start, Int32 bitsleft) { UInt64 skipped = 0; for (Int32 i = start; i < (keysBytes * 8); ++i) { --bitsleft; BitsUtilities.FlipBit(k2, 0, keysBytes, i); Byte[] h = hash.ComputeHash(k2); UnsafeBuffer.BlockCopy(h, 0, h2, 0, hashBytes); if (NativeMethods.EqualSequences(h1, h2)) { if (diffs.Count < DT_MAXIMUMERRORS) { Byte[] diff = new Byte[keysBytes]; for (Int32 j = 0; j < keysBytes; ++j) { diff[j] = (Byte)(k1[j] ^ k2[j]); } diffs.Add(diff); } else { ++skipped; } } if (bitsleft > 0) { skipped += DifferentialTestRecursion(diffs, hash, keysBytes, k1, k2, hashBytes, h1, h2, i + 1, bitsleft); } BitsUtilities.FlipBit(k2, 0, keysBytes, i); ++bitsleft; } return(skipped); }
public void ValidationTest(String hashIdentifier, UInt32 expected) { Hash hash0 = m_TestsFixture.CreateHash(hashIdentifier, 0u); Int32 hashBytes = hash0.Length / 8; Byte[] buffer = new Byte[256]; Byte[] bufferFinal = new Byte[hashBytes * 256]; for (Int32 i = 0; i < 256; ++i) { buffer[i] = (Byte)i; Hash hashi = m_TestsFixture.CreateHash(hashIdentifier, (UInt32)(256 - i)); Byte[] hi = hashi.ComputeHash(buffer, 0, i); UnsafeBuffer.BlockCopy(hi, 0, bufferFinal, i * hashBytes, hashBytes); } Byte[] h0 = hash0.ComputeHash(bufferFinal); UInt32 actual = (UInt32)((h0[0] << 0) | (h0[1] << 8) | (h0[2] << 16) | (h0[3] << 24)); Assert.Equal(expected, actual); }
public void UnsafeBufferCopy() { UnsafeBuffer.BlockCopy(src, 0, des, 0, 32); }
public static void DifferentialTest(HashInfo hashInfo) { RandomXS r = new RandomXS(0x000000B2u); Int32 hashBytes = hashInfo.Length / 8; Int32 hashBits = hashInfo.Length; Console.WriteLine("[[ DIFFERENTIAL TEST ]]"); Console.WriteLine($"Maximum Errors: {DT_MAXIMUMERRORS}"); Boolean resultOverall = true; for (Int32 i = 0; i < s_ParametersDT.Length; ++i) { dynamic p = s_ParametersDT[i]; Int32 keysBytes = p.KeysBytes; Int32 keysBits = keysBytes * 8; Byte[] key1 = new Byte[keysBytes]; Byte[] key2 = new Byte[keysBytes]; Int32 bits = p.Bits; Int32 repetitions = p.Repetitions; Int32 steps = repetitions / 10; Double tests = StatsUtilities.ChooseUpToK(keysBits, p.Bits) * repetitions; Double expectedCollisions = Math.Round(tests / Math.Pow(2.0d, hashBits)); Console.WriteLine($"> Bits: 1-{bits}"); Console.WriteLine($" Repetitions: {repetitions}"); Console.WriteLine($" Tests: {tests:F0}"); Console.WriteLine($" Expected Collisions: {expectedCollisions:F0}"); Console.Write(" Result: "); Byte[] h2 = new Byte[hashBytes]; UInt64 skipped = 0; List <Byte[]> diffs = new List <Byte[]>(DT_MAXIMUMERRORS); for (Int32 j = 0; j < repetitions; ++j) { if ((j % steps) == 0) { Console.Write((skipped > 0) ? "!" : "."); } r.NextBytes(key1); UnsafeBuffer.BlockCopy(key1, 0, key2, 0, keysBytes); Hash hash = hashInfo.Initializer(r.NextValue()); Byte[] h1 = hash.ComputeHash(key1); skipped += DifferentialTestRecursion(diffs, hash, keysBytes, key1, key2, hashBytes, h1, h2, 0, p.Bits); } Boolean result = true; if (skipped > 0) { result = false; Console.WriteLine(" FAILED"); Console.WriteLine(" - Errors Threshold Exceeded"); } else { Int32 ignoredCollisions = DifferentialTestIgnored(diffs, ref result); Console.WriteLine(result ? " PASSED" : " FAILED"); Console.WriteLine($" - Observed Collisions: {diffs.Count} ({ignoredCollisions} Ignored)"); } resultOverall &= result; } Console.WriteLine($"Test Result: {(resultOverall ? "PASSED" : "FAILED")}"); }