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")}"); }
public static void AvalancheTest(HashInfo hashInfo) { RandomXS r = new RandomXS(0x000000B0u); Hash hash = hashInfo.Initializer(r.NextValue()); Int32 hashBytes = hashInfo.Length / 8; Int32 hashBits = hashInfo.Length; Console.WriteLine("[[ AVALANCHE TEST ]]"); Boolean resultOverall = true; for (Int32 i = 0; i < s_ParametersAT.Length; ++i) { dynamic p = s_ParametersAT[i]; Int32 keyBytes = p.KeysBytes; Int32 keyBits = keyBytes * 8; Byte[] key = new Byte[p.KeysBytes]; Int32 repetitions = p.Repetitions; Int32 step = repetitions / 10; Console.WriteLine($"> Keys Length: {keyBytes} Bytes"); Console.WriteLine($" Repetitions: {repetitions}"); Console.Write(" Result: "); Int32 binsCount = keyBits * hashBits; Int32[] bins = new Int32[keyBits * hashBits]; for (Int32 j = 0; j < repetitions; ++j) { if ((j % step) == 0) { Console.Write("."); } r.NextBytes(key); Byte[] h0 = hash.ComputeHash(key); Int32 binsIndex = 0; for (Int32 keyBit = 0; keyBit < keyBits; ++keyBit) { BitsUtilities.FlipBit(key, 0, keyBytes, keyBit); Byte[] hi = hash.ComputeHash(key); BitsUtilities.FlipBit(key, 0, keyBytes, keyBit); for (Int32 hashBit = 0; hashBit < hashBits; ++hashBit) { Byte a = BitsUtilities.GetBit(h0, 0, hashBytes, hashBit); Byte b = BitsUtilities.GetBit(hi, 0, hashBytes, hashBit); bins[binsIndex++] += a ^ b; } } } Double worstBias = 0.0d; for (Int32 j = 0; j < binsCount; ++j) { Double c = (Double)bins[j] / repetitions; Double bias = Math.Abs((c * 2.0d) - 1.0d); if (bias > worstBias) { worstBias = bias; } } Boolean result = (worstBias <= 0.01d); Console.WriteLine(result ? " PASSED" : " FAILED"); Console.WriteLine($" - Worst Bias: {(worstBias.Equals(0.0d) ? "Unbiased" : $"{(worstBias * 100.0d):F2}%")}"); resultOverall &= result; } Console.WriteLine($"Test Result: {(resultOverall ? "PASSED" : "FAILED")}"); }
public static void BitIndependenceCriterionTest(HashInfo hashInfo) { RandomXS r = new RandomXS(0x000000B1u); Hash hash = hashInfo.Initializer(r.NextValue()); Int32 hashBytes = hashInfo.Length / 8; Int32 hashBits = hashInfo.Length; Int32 pageSize = hashBits * hashBits * 4; Int32 keyBytes = BICT_KEYSBYTES; Int32 keyBits = keyBytes * 8; Byte[] key = new Byte[keyBytes]; Double biasFactor = BICT_REPETITIONS / 2.0d; Int32 step = keyBits / 10; Console.WriteLine("[[ BIT INDEPENDENCE CRITERION TEST ]]"); Console.Write("Result: "); Int32[] bins = new Int32[keyBits * pageSize]; for (Int32 keyBit = 0; keyBit < keyBits; ++keyBit) { if ((keyBit % step) == 0) { Console.Write("."); } Int32 pageOffset = keyBit * pageSize; for (Int32 irep = 0; irep < BICT_REPETITIONS; ++irep) { r.NextBytes(key); Byte[] h1 = hash.ComputeHash(key); BitsUtilities.FlipBit(key, 0, keyBytes, keyBit); Byte[] h2 = hash.ComputeHash(key); Byte[] d = new Byte[hashBytes]; for (Int32 i = 0; i < hashBytes; ++i) { d[i] = (Byte)(h1[i] ^ h2[i]); } for (Int32 hashBit1 = 0; hashBit1 < hashBits - 1; ++hashBit1) { for (Int32 hashBit2 = hashBit1 + 1; hashBit2 < hashBits; ++hashBit2) { Int32 x = BitsUtilities.GetBit(d, 0, hashBytes, hashBit1) | (BitsUtilities.GetBit(d, 0, hashBytes, hashBit2) << 1); ++bins[pageOffset + (((hashBit1 * hashBits) + hashBit2) * 4) + x]; } } } } Double worstBias = 0.0d; Int32 worstKeyBit = -1; Int32 worstHashBit1 = -1; Int32 worstHashBit2 = -1; for (Int32 hashBit1 = 0; hashBit1 < hashBits - 1; ++hashBit1) { for (Int32 hashBit2 = hashBit1 + 1; hashBit2 < hashBits; ++hashBit2) { for (Int32 keyBit = 0; keyBit < keyBits; ++keyBit) { Int32 binsOffset = (keyBit * pageSize) + ((hashBit1 * hashBits) + hashBit2) * 4; for (Int32 b = 0; b < 4; ++b) { Double c = bins[binsOffset + b] / biasFactor; Double bias = Math.Abs((c * 2.0d) - 1.0d); if (bias > worstBias) { worstBias = bias; worstKeyBit = keyBit; worstHashBit1 = hashBit1; worstHashBit2 = hashBit2; } } } } } Boolean result = (worstBias <= 0.05d); Console.WriteLine(result ? " PASSED" : " FAILED"); Console.WriteLine($" - Worst Bias: {(worstBias.Equals(0.0d) ? "Unbiased" : $"{(worstBias * 100.0d):F2}% (Key Bit: {worstKeyBit} | Hash Bit 1: {worstHashBit1} | Hash Bit 2: {worstHashBit2})")}"); }
private static void RunTests(String[] hashes, ValidationTestsSelection validationTestsSelection, Boolean qualityTests, Boolean speedTests) { Process process = Process.GetCurrentProcess(); IntPtr affinityNew = (IntPtr)(1 << (Environment.ProcessorCount - 1)); IntPtr affinityOld = process.ProcessorAffinity; process.ProcessorAffinity = affinityNew; Thread.BeginThreadAffinity(); ProcessThread thread = NativeMethods.GetCurrentThread(); if (thread != null) { thread.ProcessorAffinity = affinityNew; } for (Int32 i = 0; i < s_HashInfos.Length; ++i) { HashInfo hashInfo = s_HashInfos[i]; String hashInfoName = hashInfo.Name; if (!hashes.Contains(hashInfoName)) { continue; } String title = $"# HASH: {hashInfoName} ({hashInfo.Length} Bits) #"; String frame = new String('#', title.Length); Console.WriteLine(frame); Console.WriteLine(title); Console.WriteLine(frame); if (validationTestsSelection != ValidationTestsSelection.None) { Console.WriteLine(); ValidationTests.VerificationTest(hashInfo); } if (validationTestsSelection == ValidationTestsSelection.All) { Console.WriteLine(); ValidationTests.CombinationsTest(hashInfo); Console.WriteLine(); ValidationTests.CyclicKeysTest(hashInfo); Console.WriteLine(); ValidationTests.FlippedKeysTest(hashInfo); Console.WriteLine(); ValidationTests.KeySetsTest(hashInfo); Console.WriteLine(); ValidationTests.PaddedKeysTest(hashInfo); Console.WriteLine(); ValidationTests.SparseKeysTest(hashInfo); Console.WriteLine(); ValidationTests.TwoBytesTest(hashInfo); Console.WriteLine(); ValidationTests.UniformKeysTest(hashInfo); Console.WriteLine(); ValidationTests.WindowedKeysTest(hashInfo); Console.WriteLine(); ValidationTests.WordsTest(hashInfo); } if (qualityTests) { Console.WriteLine(); QualityTests.AvalancheTest(hashInfo); Console.WriteLine(); QualityTests.BitIndependenceCriterionTest(hashInfo); Console.WriteLine(); QualityTests.DifferentialTest(hashInfo); } if (speedTests) { Console.WriteLine(); SpeedTests.BulkSpeedTest(hashInfo); Console.WriteLine(); SpeedTests.ChunksSpeedTest(hashInfo); } Int32 hashInfoIndex = Array.IndexOf(hashes, hashInfoName); if (hashInfoIndex != (hashes.Length - 1)) { Console.WriteLine(); } } process.ProcessorAffinity = affinityOld; if (thread != null) { thread.ProcessorAffinity = affinityOld; } Thread.EndThreadAffinity(); }