blob: dda137c255614fd6ff8797b985464d871f7bb650 [file] [log] [blame]
tanjent@gmail.comad4b3632010-11-05 01:20:58 +00001#include "KeysetTest.h"
2
3#include "Random.h"
4
5//-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +00006// This should hopefully be a thorough and uambiguous test of whether a hash
7// is correctly implemented on a given platform
tanjent@gmail.comad4b3632010-11-05 01:20:58 +00008
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +00009bool VerificationTest ( pfHash hash, const int hashbits, uint32_t expected, bool verbose )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000010{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000011 const int hashbytes = hashbits / 8;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000012
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000013 uint8_t * key = new uint8_t[256];
14 uint8_t * hashes = new uint8_t[hashbytes * 256];
15 uint8_t * final = new uint8_t[hashbytes];
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000016
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000017 memset(key,0,256);
18 memset(hashes,0,hashbytes*256);
19 memset(final,0,hashbytes);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000020
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000021 for(int i = 0; i < 256; i++)
22 {
23 key[i] = (uint8_t)i;
24
25 hash(key,i,0,&hashes[i*hashbytes]);
26 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000027
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000028 //----------
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000029
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000030 hash(hashes,hashbytes*256,0,final);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000031
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000032 uint32_t verification = (final[0] << 0) | (final[1] << 8) | (final[2] << 16) | (final[3] << 24);
33
34 delete [] key;
35 delete [] hashes;
36 delete [] final;
37
38 //----------
39
40 if(expected != verification)
41 {
42 if(verbose) printf("Verification value 0x%08X : Failed! (Expected 0x%08x)\n",verification,expected);
43 return false;
44 }
45 else
46 {
47 if(verbose) printf("Verification value 0x%08X : Passed!\n",verification);
48 return true;
49 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000050}
51
52//----------------------------------------------------------------------------
tanjent@gmail.combabb5532011-02-28 06:03:12 +000053// Basic sanity checks -
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000054
tanjent@gmail.combabb5532011-02-28 06:03:12 +000055// A hash function should not be reading outside the bounds of the key.
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000056
tanjent@gmail.combabb5532011-02-28 06:03:12 +000057// Flipping a bit of a key should, with overwhelmingly high probability,
58// result in a different hash.
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000059
tanjent@gmail.combabb5532011-02-28 06:03:12 +000060// Hashing the same key twice should always produce the same result.
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000061
tanjent@gmail.combabb5532011-02-28 06:03:12 +000062// The memory alignment of the key should not affect the hash result.
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000063
tanjent@gmail.combabb5532011-02-28 06:03:12 +000064bool SanityTest ( pfHash hash, const int hashbits )
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000065{
66 printf("Running sanity check 1");
aappleby@google.com7f20a312011-03-21 20:55:06 +000067
68 Rand r(883741);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000069
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000070 bool result = true;
tanjent@gmail.com9d17d0b2010-11-17 04:07:51 +000071
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000072 const int hashbytes = hashbits/8;
73 const int reps = 10;
74 const int keymax = 128;
75 const int pad = 16;
76 const int buflen = keymax + pad*3;
77
78 uint8_t * buffer1 = new uint8_t[buflen];
79 uint8_t * buffer2 = new uint8_t[buflen];
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000080
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000081 uint8_t * hash1 = new uint8_t[hashbytes];
82 uint8_t * hash2 = new uint8_t[hashbytes];
tanjent@gmail.combabb5532011-02-28 06:03:12 +000083
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000084 //----------
85
86 for(int irep = 0; irep < reps; irep++)
87 {
88 if(irep % (reps/10) == 0) printf(".");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000089
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000090 for(int len = 4; len <= keymax; len++)
91 {
92 for(int offset = pad; offset < pad*2; offset++)
93 {
94 uint8_t * key1 = &buffer1[pad];
95 uint8_t * key2 = &buffer2[pad+offset];
tanjent@gmail.combabb5532011-02-28 06:03:12 +000096
aappleby@google.com7f20a312011-03-21 20:55:06 +000097 r.rand_p(buffer1,buflen);
98 r.rand_p(buffer2,buflen);
tanjent@gmail.combabb5532011-02-28 06:03:12 +000099
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000100 memcpy(key2,key1,len);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000101
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000102 hash(key1,len,0,hash1);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000103
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000104 for(int bit = 0; bit < (len * 8); bit++)
105 {
106 // Flip a bit, hash the key -> we should get a different result.
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000107
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000108 flipbit(key2,len,bit);
109 hash(key2,len,0,hash2);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000110
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000111 if(memcmp(hash1,hash2,hashbytes) == 0)
112 {
113 result = false;
114 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000115
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000116 // Flip it back, hash again -> we should get the original result.
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000117
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000118 flipbit(key2,len,bit);
119 hash(key2,len,0,hash2);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000120
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000121 if(memcmp(hash1,hash2,hashbytes) != 0)
122 {
123 result = false;
124 }
125 }
126 }
127 }
128 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000129
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000130 if(result == false)
131 {
132 printf("*********FAIL*********\n");
133 }
134 else
135 {
136 printf("PASS\n");
137 }
tanjent@gmail.com9d17d0b2010-11-17 04:07:51 +0000138
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000139 delete [] hash1;
140 delete [] hash2;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000141
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000142 return result;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000143}
144
145//----------------------------------------------------------------------------
146// Appending zero bytes to a key should always cause it to produce a different
147// hash value
148
149void AppendedZeroesTest ( pfHash hash, const int hashbits )
150{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000151 printf("Running sanity check 2");
aappleby@google.com7f20a312011-03-21 20:55:06 +0000152
153 Rand r(173994);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000154
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000155 const int hashbytes = hashbits/8;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000156
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000157 for(int rep = 0; rep < 100; rep++)
158 {
159 if(rep % 10 == 0) printf(".");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000160
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000161 unsigned char key[256];
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000162
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000163 memset(key,0,sizeof(key));
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000164
aappleby@google.com7f20a312011-03-21 20:55:06 +0000165 r.rand_p(key,32);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000166
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000167 uint32_t h1[16];
168 uint32_t h2[16];
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000169
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000170 memset(h1,0,hashbytes);
171 memset(h2,0,hashbytes);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000172
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000173 for(int i = 0; i < 32; i++)
174 {
175 hash(key,32+i,0,h1);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000176
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000177 if(memcmp(h1,h2,hashbytes) == 0)
178 {
179 printf("\n*********FAIL*********\n");
180 return;
181 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000182
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000183 memcpy(h2,h1,hashbytes);
184 }
185 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000186
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000187 printf("PASS\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000188}
189
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000190//-----------------------------------------------------------------------------