void test ( hashfunc<hashtype> hash, HashInfo* info ) { const int hashbits = sizeof(hashtype) * 8; printf("-------------------------------------------------------------------------------\n"); // eventual initializers #if defined(__SSE4_2__) && defined(__x86_64__) if(info->hash == clhash_test) clhash_init(); #endif #ifdef HAVE_HIGHWAYHASH if(info->hash == HighwayHash64_test) HighwayHash_init(); #endif //----------------------------------------------------------------------------- // Sanity tests if(g_testVerifyAll) { printf("[[[ VerifyAll Tests ]]]\n\n"); fflush(NULL); SelfTest(); printf("PASS\n\n"); fflush(NULL); // if not it does exit(1) } printf("--- Testing %s \"%s\" %s\n\n", info->name, info->desc, quality_str[info->quality]); fflush(NULL); if(g_testSanity || g_testAll) { printf("[[[ Sanity Tests ]]]\n\n"); fflush(NULL); VerificationTest(hash,hashbits,info->verification,true); SanityTest(hash,hashbits); AppendedZeroesTest(hash,hashbits); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Speed tests if(g_testSpeed || g_testAll) { double sum = 0.0; printf("[[[ Speed Tests ]]]\n\n"); fflush(NULL); BulkSpeedTest(info->hash,info->verification); printf("\n"); fflush(NULL); for(int i = 1; i < 32; i++) { sum += TinySpeedTest(hashfunc<hashtype>(info->hash),sizeof(hashtype),i,info->verification,true); } sum = sum / 31.0; printf("Average %6.3f cycles/hash\n",sum); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Avalanche tests // 1m30 for xxh3 // 13m for xxh3 with --extra // 3m for farmhash128_c (was 7m with 512,1024) if(g_testAvalanche || g_testAll) { printf("[[[ Avalanche Tests ]]]\n\n"); fflush(NULL); bool result = true; bool verbose = g_drawDiagram; //.......... progress dots result &= AvalancheTest< Blob< 24>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 32>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 40>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 48>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 56>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 64>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 72>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 80>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob< 96>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<112>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<128>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<160>, hashtype > (hash,300000,verbose); if(g_testExtra) { result &= AvalancheTest< Blob<192>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<224>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<256>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<320>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<384>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<448>, hashtype > (hash,300000,verbose); } if (g_testExtra || info->hashbits <= 64) { result &= AvalancheTest< Blob<512>, hashtype > (hash,300000,verbose); } if(g_testExtra) { result &= AvalancheTest< Blob<640>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<768>, hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<896>, hashtype > (hash,300000,verbose); } if (g_testExtra || info->hashbits <= 64) { result &= AvalancheTest< Blob<1024>,hashtype > (hash,300000,verbose); } if(g_testExtra) { result &= AvalancheTest< Blob<1280>,hashtype > (hash,300000,verbose); result &= AvalancheTest< Blob<1536>,hashtype > (hash,300000,verbose); } if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Keyset 'Sparse' - keys with all bits 0 except a few // 3m30 for xxh3 // 14m for xxh3 with --extra // 6m30 for farmhash128_c (was too much with >= 512) if(g_testSparse || g_testAll) { printf("[[[ Keyset 'Sparse' Tests ]]]\n\n"); fflush(NULL); bool result = true; result &= SparseKeyTest< 16,hashtype>(hash,9,true,true,true, g_drawDiagram); result &= SparseKeyTest< 24,hashtype>(hash,8,true,true,true, g_drawDiagram); result &= SparseKeyTest< 32,hashtype>(hash,7,true,true,true, g_drawDiagram); result &= SparseKeyTest< 40,hashtype>(hash,6,true,true,true, g_drawDiagram); result &= SparseKeyTest< 48,hashtype>(hash,6,true,true,true, g_drawDiagram); result &= SparseKeyTest< 56,hashtype>(hash,5,true,true,true, g_drawDiagram); result &= SparseKeyTest< 64,hashtype>(hash,5,true,true,true, g_drawDiagram); result &= SparseKeyTest< 72,hashtype>(hash,5,true,true,true, g_drawDiagram); result &= SparseKeyTest< 96,hashtype>(hash,4,true,true,true, g_drawDiagram); if (g_testExtra) { result &= SparseKeyTest< 112,hashtype>(hash,4,true,true,true, g_drawDiagram); result &= SparseKeyTest< 128,hashtype>(hash,4,true,true,true, g_drawDiagram); result &= SparseKeyTest< 144,hashtype>(hash,4,true,true,true, g_drawDiagram); } result &= SparseKeyTest< 160,hashtype>(hash,4,true,true,true, g_drawDiagram); if (g_testExtra) { result &= SparseKeyTest< 192,hashtype>(hash,4,true,true,true, g_drawDiagram); } result &= SparseKeyTest< 256,hashtype>(hash,3,true,true,true, g_drawDiagram); if (g_testExtra) { result &= SparseKeyTest< 288,hashtype>(hash,3,true,true,true, g_drawDiagram); result &= SparseKeyTest< 320,hashtype>(hash,3,true,true,true, g_drawDiagram); result &= SparseKeyTest< 384,hashtype>(hash,3,true,true,true, g_drawDiagram); result &= SparseKeyTest< 448,hashtype>(hash,3,true,true,true, g_drawDiagram); } else { if (info->hashbits > 64) //too long goto END_Sparse; } result &= SparseKeyTest< 512,hashtype>(hash,3,true,true,true, g_drawDiagram); if (g_testExtra) { result &= SparseKeyTest< 640,hashtype>(hash,3,true,true,true, g_drawDiagram); result &= SparseKeyTest< 768,hashtype>(hash,3,true,true,true, g_drawDiagram); result &= SparseKeyTest< 896,hashtype>(hash,2,true,true,true, g_drawDiagram); } result &= SparseKeyTest<1024,hashtype>(hash,2,true,true,true, g_drawDiagram); if (g_testExtra) { result &= SparseKeyTest<1280,hashtype>(hash,2,true,true,true, g_drawDiagram); result &= SparseKeyTest<1536,hashtype>(hash,2,true,true,true, g_drawDiagram); } result &= SparseKeyTest<2048,hashtype>(hash,2,true,true,true, g_drawDiagram); if (g_testExtra) { result &= SparseKeyTest<3072,hashtype>(hash,2,true,true,true, g_drawDiagram); result &= SparseKeyTest<4096,hashtype>(hash,2,true,true,true, g_drawDiagram); result &= SparseKeyTest<6144,hashtype>(hash,2,true,true,true, g_drawDiagram); result &= SparseKeyTest<8192,hashtype>(hash,2,true,true,true, g_drawDiagram); result &= SparseKeyTest<9992,hashtype>(hash,2,true,true,true, g_drawDiagram); } END_Sparse: if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Keyset 'Permutation' - all possible combinations of a set of blocks // 9m with xxh3 and maxlen=23, 4m15 with maxlen=22 // 120m for farmhash128_c with maxlen=18, 1m20 FAIL with maxlen=12 // 1m20 PASS with maxlen=14,16,17 if(g_testPermutation || g_testAll) { const int maxlen = g_testExtra ? 23 : info->hashbits > 64 ? 17 : 22; { // This one breaks lookup3, surprisingly printf("[[[ Keyset 'Permutation' Tests ]]]\n\n"); printf("Combination Lowbits Tests:\n"); fflush(NULL); bool result = true; uint32_t blocks[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; result &= CombinationKeyTest<hashtype>(hash,7,blocks, sizeof(blocks) / sizeof(uint32_t), true,true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination Highbits Tests\n"); fflush(NULL); bool result = true; uint32_t blocks[] = { 0x00000000, 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000 }; result &= CombinationKeyTest(hash,7,blocks,sizeof(blocks) / sizeof(uint32_t), true,true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination Hi-Lo Tests:\n"); bool result = true; uint32_t blocks[] = { 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x80000000, 0x40000000, 0xC0000000, 0x20000000, 0xA0000000, 0x60000000, 0xE0000000 }; result &= CombinationKeyTest<hashtype>(hash,6,blocks,sizeof(blocks) / sizeof(uint32_t), true,true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 0x8000000 Tests:\n"); fflush(NULL); bool result = true; uint32_t blocks[] = { 0x00000000, 0x80000000, }; result &= CombinationKeyTest(hash, maxlen, blocks, sizeof(blocks) / sizeof(uint32_t), true,true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 0x0000001 Tests:\n"); bool result = true; uint32_t blocks[] = { 0x00000000, 0x00000001, }; result &= CombinationKeyTest(hash, maxlen, blocks, sizeof(blocks) / sizeof(uint32_t), true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 0x800000000000000 Tests:\n"); fflush(NULL); bool result = true; uint64_t blocks[] = { 0x0000000000000000ULL, 0x8000000000000000ULL, }; result &= CombinationKeyTest(hash, maxlen, blocks, sizeof(blocks) / sizeof(uint64_t), true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 0x000000000000001 Tests:\n"); fflush(NULL); bool result = true; uint64_t blocks[] = { 0x0000000000000000ULL, 0x0000000000000001ULL, }; result &= CombinationKeyTest(hash, maxlen, blocks, sizeof(blocks) / sizeof(uint64_t), true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 16-bytes [0-1] Tests:\n"); fflush(NULL); bool result = true; block16 blocks[2]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[0] = 1; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, 2, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 16-bytes [0-last] Tests:\n"); fflush(NULL); bool result = true; size_t const nbElts = 2; block16 blocks[nbElts]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[sizeof(blocks[0].c)-1] = 0x80; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, nbElts, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 32-bytes [0-1] Tests:\n"); fflush(NULL); bool result = true; block32 blocks[2]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[0] = 1; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, 2, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 32-bytes [0-last] Tests:\n"); fflush(NULL); bool result = true; size_t const nbElts = 2; block32 blocks[nbElts]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[sizeof(blocks[0].c)-1] = 0x80; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, nbElts, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 64-bytes [0-1] Tests:\n"); fflush(NULL); bool result = true; block64 blocks[2]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[0] = 1; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, 2, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 64-bytes [0-last] Tests:\n"); fflush(NULL); bool result = true; size_t const nbElts = 2; block64 blocks[nbElts]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[sizeof(blocks[0].c)-1] = 0x80; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, nbElts, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 128-bytes [0-1] Tests:\n"); fflush(NULL); bool result = true; block128 blocks[2]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[0] = 1; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, 2, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } { printf("Combination 128-bytes [0-last] Tests:\n"); fflush(NULL); bool result = true; size_t const nbElts = 2; block128 blocks[nbElts]; memset(blocks, 0, sizeof(blocks)); blocks[0].c[sizeof(blocks[0].c)-1] = 0x80; // presumes little endian result &= CombinationKeyTest(hash, maxlen, blocks, nbElts, true, true, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } } //----------------------------------------------------------------------------- // Keyset 'Window' // Skip distribution test for these - they're too easy to distribute well, // and it generates a _lot_ of testing. // 11s for crc32_hw, 28s for xxh3 // 51s for crc32_hw --extra // 180m for farmhash128_c with 20 windowbits, // 0.19s with windowbits=10, 2s for 14, 9s for 16, 37s for 18 if(g_testWindow || g_testAll) { printf("[[[ Keyset 'Window' Tests ]]]\n\n"); bool result = true; bool testCollision = true; bool testDistribution = g_testExtra; const int windowbits = info->hashbits > 64 ? 18 : 20; result &= WindowedKeyTest< Blob<hashbits*2+2>, hashtype > ( hash, windowbits, testCollision, testDistribution, g_drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Keyset 'Cyclic' - keys of the form "abcdabcdabcd..." // 5s for crc32_hw // 18s for farmhash128_c if(g_testCyclic || g_testAll) { printf("[[[ Keyset 'Cyclic' Tests ]]]\n\n"); fflush(NULL); bool result = true; #if 0 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+0,8,100000, g_drawDiagram); #else result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+0,8,1000000, g_drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+1,8,1000000, g_drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+2,8,1000000, g_drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+3,8,1000000, g_drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+4,8,1000000, g_drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+8,8,1000000, g_drawDiagram); #endif if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Keyset 'TwoBytes' - all keys up to N bytes containing two non-zero bytes // 3m40 for crc32_hw (32bit), 8m30 for xxh3 --extra (64bit) // 4m16 for xxh3 // 4m50 for metrohash128crc_1 // 260m for farmhash128_c with maxlen=16, 31s with maxlen=10, 2m with 12,14,15 // With --extra this generates some huge keysets, // 128-bit tests will take ~1.3 gigs of RAM. if(g_testTwoBytes || g_testAll) { printf("[[[ Keyset 'TwoBytes' Tests ]]]\n\n"); fflush(NULL); bool result = true; int maxlen = 24; if (!g_testExtra && (info->hashbits > 32)) { maxlen = (info->hashbits < 128) ? 20 : 15; } for(int i = 4; i <= maxlen; i += 4) { result &= TwoBytesTest2<hashtype>(hash, i, g_drawDiagram); } if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } // Moment Chi-Square test, measuring the probability of the // lowest 32 bits set over the whole key space. Not where the bits are, but how many. // See e.g. https://www.statlect.com/fundamentals-of-probability/moment-generating-function // 10s (16 step interval until 0x7ffffff) // 20s (16 step interval until 0xcffffff) // step time // 1 300s // 2 150s // 3 90s // 7 35s // 13 20s // 16 12s if(g_testMomentChi2 || g_testAll) { printf("[[[ 'MomentChi2' Tests ]]]\n\n"); bool result = true; result &= MomentChi2Test(info); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // LongNeighbors - collisions between long messages of low Hamming distance // esp. for testing separate word and then byte-wise processing of unaligned // rest parts. Only with --test=LongNeighbors or --extra // 10s for fasthash32 // 7m with xxh3 (64bit) // 10m30s with farmhash128_c // Not yet included for licensing reasons #if 0 if(g_testLongNeighbors || (g_testAll && g_testExtra)) { printf("[[[ 'LongNeighbors' Tests ]]]\n\n"); bool result = true; result &= testLongNeighbors(info->hash, info->hashbits, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } #endif //----------------------------------------------------------------------------- // Keyset 'Text' if(g_testText || g_testAll) { printf("[[[ Keyset 'Text' Tests ]]]\n\n"); bool result = true; const char * alnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; result &= TextKeyTest( hash, "Foo", alnum, 4, "Bar", g_drawDiagram ); result &= TextKeyTest( hash, "FooBar", alnum, 4, "", g_drawDiagram ); result &= TextKeyTest( hash, "", alnum, 4, "FooBar", g_drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Keyset 'Zeroes' if(g_testZeroes || g_testAll) { printf("[[[ Keyset 'Zeroes' Tests ]]]\n\n"); bool result = true; result &= ZeroKeyTest<hashtype>( hash, g_drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Keyset 'Seed' if(g_testSeed || g_testAll) { printf("[[[ Keyset 'Seed' Tests ]]]\n\n"); bool result = true; result &= SeedTest<hashtype>( hash, 5000000, g_drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Differential tests // 5m30 with xxh3 if(g_testDiff || g_testAll) { printf("[[[ Diff 'Differential' Tests ]]]\n\n"); fflush(NULL); bool result = true; bool dumpCollisions = g_drawDiagram; // from --verbose result &= DiffTest< Blob<64>, hashtype >(hash,5,1000,dumpCollisions); result &= DiffTest< Blob<128>, hashtype >(hash,4,1000,dumpCollisions); result &= DiffTest< Blob<256>, hashtype >(hash,3,1000,dumpCollisions); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Differential-distribution tests // 2m40 with xxh3 if(g_testDiffDist || g_testAll) { printf("[[[ DiffDist 'Differential Distribution' Tests ]]]\n\n"); fflush(NULL); bool result = true; result &= DiffDistTest2<uint64_t,hashtype>(hash, g_drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } //----------------------------------------------------------------------------- // Bit Independence Criteria. Interesting, but doesn't tell us much about // collision or distribution. For 128bit hashes only with --extra // 4m with xxh3 // 152m with farmhash128_c with reps=1000000, => 8m with 100000 if(g_testBIC || (info->hashbits > 64 && g_testExtra)) { printf("[[[ 'BIC' (Bit Independence Criteria) Tests ]]]\n\n"); fflush(NULL); bool result = true; if (info->hashbits > 64) { result &= BicTest3<Blob<128>,hashtype>(hash,100000,g_drawDiagram); } else { const long reps = 64000000/info->hashbits; //result &= BicTest<uint64_t,hashtype>(hash,2000000); result &= BicTest3<Blob<88>,hashtype>(hash,(int)reps,g_drawDiagram); } if(!result) printf("*********FAIL*********\n"); printf("\n"); fflush(NULL); } }
void test ( hashfunc<hashtype> hash, HashInfo * info ) { const int hashbits = sizeof(hashtype) * 8; printf("-------------------------------------------------------------------------------\n"); printf("--- Testing %s (%s)\n\n",info->name,info->desc); //----------------------------------------------------------------------------- // Sanity tests if(g_testSanity || g_testAll) { printf("[[[ Sanity Tests ]]]\n\n"); VerificationTest(hash,hashbits,info->verification,true); SanityTest(hash,hashbits); AppendedZeroesTest(hash,hashbits); printf("\n"); } //----------------------------------------------------------------------------- // Speed tests if(g_testSpeed || g_testAll) { printf("[[[ Speed Tests ]]]\n\n"); SetAffinity((1 << 2)); // Run speed tests on 3rd CPU to ensure that RDTSC always the the same core BulkSpeedTest(info->hash,info->hashbits,info->verification); printf("\n"); const int max_keysize = 66; TinySpeedTest(info->hash,info->hashbits,max_keysize,info->verification,true); ResetAffinity(); // Use all cores for the rest of code printf("\n"); } //----------------------------------------------------------------------------- // Avalanche tests if(g_testAvalanche || g_testAll) { printf("[[[ Avalanche Tests ]]]\n\n"); bool result = true; result &= AvalancheTest< Blob< 32>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 40>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 48>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 56>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 64>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 72>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 80>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 88>, hashtype > (hash,300000); result &= AvalancheTest< Blob< 96>, hashtype > (hash,300000); result &= AvalancheTest< Blob<104>, hashtype > (hash,300000); result &= AvalancheTest< Blob<112>, hashtype > (hash,300000); result &= AvalancheTest< Blob<120>, hashtype > (hash,300000); result &= AvalancheTest< Blob<128>, hashtype > (hash,300000); result &= AvalancheTest< Blob<136>, hashtype > (hash,300000); result &= AvalancheTest< Blob<144>, hashtype > (hash,300000); result &= AvalancheTest< Blob<152>, hashtype > (hash,300000); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'Cyclic' - keys of the form "abcdabcdabcd..." if(g_testCyclic || g_testAll) { printf("[[[ Keyset 'Cyclic' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+0,8,10000000,drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+1,8,10000000,drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+2,8,10000000,drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+3,8,10000000,drawDiagram); result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+4,8,10000000,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'TwoBytes' - all keys up to N bytes containing two non-zero bytes // This generates some huge keysets, 128-bit tests will take ~1.3 gigs of RAM. if(g_testTwoBytes || g_testAll) { printf("[[[ Keyset 'TwoBytes' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; for(int i = 4; i <= 20; i += 4) { result &= TwoBytesTest2<hashtype>(hash,i,drawDiagram); } if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'Sparse' - keys with all bits 0 except a few if(g_testSparse || g_testAll) { printf("[[[ Keyset 'Sparse' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; result &= SparseKeyTest< 32,hashtype>(hash,6,true,true,true,drawDiagram); result &= SparseKeyTest< 40,hashtype>(hash,6,true,true,true,drawDiagram); result &= SparseKeyTest< 48,hashtype>(hash,5,true,true,true,drawDiagram); result &= SparseKeyTest< 56,hashtype>(hash,5,true,true,true,drawDiagram); result &= SparseKeyTest< 64,hashtype>(hash,5,true,true,true,drawDiagram); result &= SparseKeyTest< 96,hashtype>(hash,4,true,true,true,drawDiagram); result &= SparseKeyTest< 256,hashtype>(hash,3,true,true,true,drawDiagram); result &= SparseKeyTest<2048,hashtype>(hash,2,true,true,true,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'Permutation' - all possible combinations of a set of blocks if(g_testPermutation || g_testAll) { { // This one breaks lookup3, surprisingly printf("[[[ Keyset 'Combination Lowbits' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; uint32_t blocks[] = { 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, }; result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } { printf("[[[ Keyset 'Combination Highbits' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; uint32_t blocks[] = { 0x00000000, 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000 }; result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } { printf("[[[ Keyset 'Combination 0x8000000' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; uint32_t blocks[] = { 0x00000000, 0x80000000, }; result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } { printf("[[[ Keyset 'Combination 0x0000001' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; uint32_t blocks[] = { 0x00000000, 0x00000001, }; result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } { printf("[[[ Keyset 'Combination Hi-Lo' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; uint32_t blocks[] = { 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x80000000, 0x40000000, 0xC0000000, 0x20000000, 0xA0000000, 0x60000000, 0xE0000000 }; result &= CombinationKeyTest<hashtype>(hash,6,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram); if(!result) printf("*********FAIL*********\n"); printf("\n"); } } //----------------------------------------------------------------------------- // Keyset 'Window' // Skip distribution test for these - they're too easy to distribute well, // and it generates a _lot_ of testing if(g_testWindow || g_testAll) { printf("[[[ Keyset 'Window' Tests ]]]\n\n"); bool result = true; bool testCollision = true; bool testDistribution = false; bool drawDiagram = false; result &= WindowedKeyTest< Blob<hashbits*2>, hashtype > ( hash, 20, testCollision, testDistribution, drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'Text' if(g_testText || g_testAll) { printf("[[[ Keyset 'Text' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; const char * alnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; result &= TextKeyTest( hash, "Foo", alnum,4, "Bar", drawDiagram ); result &= TextKeyTest( hash, "FooBar", alnum,4, "", drawDiagram ); result &= TextKeyTest( hash, "", alnum,4, "FooBar", drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'Zeroes' if(g_testZeroes || g_testAll) { printf("[[[ Keyset 'Zeroes' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; result &= ZeroKeyTest<hashtype>( hash, drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Keyset 'Seed' if(g_testSeed || g_testAll) { printf("[[[ Keyset 'Seed' Tests ]]]\n\n"); bool result = true; bool drawDiagram = false; result &= SeedTest<hashtype>( hash, 1000000, drawDiagram ); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Differential tests if(g_testDiff || g_testAll) { printf("[[[ Differential Tests ]]]\n\n"); bool result = true; bool dumpCollisions = false; result &= DiffTest< Blob<64>, hashtype >(hash,5,1000,dumpCollisions); result &= DiffTest< Blob<128>, hashtype >(hash,4,1000,dumpCollisions); result &= DiffTest< Blob<256>, hashtype >(hash,3,1000,dumpCollisions); if(!result) printf("*********FAIL*********\n"); printf("\n"); } //----------------------------------------------------------------------------- // Differential-distribution tests if(g_testDiffDist /*|| g_testAll*/) { printf("[[[ Differential Distribution Tests ]]]\n\n"); bool result = true; result &= DiffDistTest2<uint64_t,hashtype>(hash); printf("\n"); } //----------------------------------------------------------------------------- // Bit Independence Criteria. Interesting, but doesn't tell us much about // collision or distribution. if(g_testBIC) { printf("[[[ Bit Independence Criteria ]]]\n\n"); bool result = true; //result &= BicTest<uint64_t,hashtype>(hash,2000000); BicTest3<Blob<88>,hashtype>(hash,2000000); if(!result) printf("*********FAIL*********\n"); printf("\n"); } }