File Coverage

ext/xxHash/cli/xsum_sanity_check.c
Criterion Covered Total %
statement 0 207 0.0
branch 0 88 0.0
condition n/a
subroutine n/a
pod n/a
total 0 295 0.0


line stmt bran cond sub pod time code
1             /*
2             * xxhsum - Command line interface for xxhash algorithms
3             * Copyright (C) 2013-2020 Yann Collet
4             *
5             * GPL v2 License
6             *
7             * This program is free software; you can redistribute it and/or modify
8             * it under the terms of the GNU General Public License as published by
9             * the Free Software Foundation; either version 2 of the License, or
10             * (at your option) any later version.
11             *
12             * This program is distributed in the hope that it will be useful,
13             * but WITHOUT ANY WARRANTY; without even the implied warranty of
14             * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             * GNU General Public License for more details.
16             *
17             * You should have received a copy of the GNU General Public License along
18             * with this program; if not, write to the Free Software Foundation, Inc.,
19             * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20             *
21             * You can contact the author at:
22             * - xxHash homepage: https://www.xxhash.com
23             * - xxHash source repository: https://github.com/Cyan4973/xxHash
24             */
25              
26             #include "xsum_config.h"
27             #include "xsum_sanity_check.h"
28             #include "xsum_output.h"
29             #include
30             #include
31             #include
32             #ifndef XXH_STATIC_LINKING_ONLY
33             # define XXH_STATIC_LINKING_ONLY
34             #endif
35             #include "../xxhash.h"
36              
37             /* use #define to make them constant, required for initialization */
38             #define PRIME32 2654435761U
39             #define PRIME64 11400714785074694797ULL
40              
41             /*
42             * Fills a test buffer with pseudorandom data.
43             *
44             * This is used in the sanity check - its values must not be changed.
45             */
46 0           XSUM_API void XSUM_fillTestBuffer(XSUM_U8* buffer, size_t len)
47             {
48             XSUM_U64 byteGen = PRIME32;
49             size_t i;
50              
51 0 0         assert(buffer != NULL);
52              
53 0 0         for (i=0; i
54 0           buffer[i] = (XSUM_U8)(byteGen>>56);
55 0           byteGen *= PRIME64;
56             }
57 0           }
58              
59              
60              
61             /* ************************************************
62             * Self-test:
63             * ensure results consistency accross platforms
64             *********************************************** */
65             #if XSUM_NO_TESTS
66             XSUM_API void XSUM_sanityCheck(void)
67             {
68             XSUM_log("This version of xxhsum is not verified.\n");
69             }
70             #else
71              
72             /*
73             * Test data vectors
74             */
75             typedef struct {
76             XSUM_U32 len;
77             XSUM_U32 seed;
78             XSUM_U32 Nresult;
79             } XSUM_testdata32_t;
80              
81             typedef struct {
82             XSUM_U32 len;
83             XSUM_U64 seed;
84             XSUM_U64 Nresult;
85             } XSUM_testdata64_t;
86              
87             typedef struct {
88             XSUM_U32 len;
89             XSUM_U64 seed;
90             XXH128_hash_t Nresult;
91             } XSUM_testdata128_t;
92              
93             #define SECRET_SAMPLE_NBBYTES 4
94             typedef struct {
95             XSUM_U32 len;
96             XSUM_U8 byte[SECRET_SAMPLE_NBBYTES];
97             } XSUM_testdata_sample_t;
98              
99             /* XXH32 */
100             static const XSUM_testdata32_t XSUM_XXH32_testdata[] = {
101             { 0, 0, 0x02CC5D05U },
102             { 0, PRIME32, 0x36B78AE7U },
103             { 1, 0, 0xCF65B03EU },
104             { 1, PRIME32, 0xB4545AA4U },
105             { 14, 0, 0x1208E7E2U },
106             { 14, PRIME32, 0x6AF1D1FEU },
107             { 222, 0, 0x5BD11DBDU },
108             { 222, PRIME32, 0x58803C5FU }
109             };
110              
111             /* XXH64 */
112             static const XSUM_testdata64_t XSUM_XXH64_testdata[] = {
113             { 0, 0, 0xEF46DB3751D8E999ULL },
114             { 0, PRIME32, 0xAC75FDA2929B17EFULL },
115             { 1, 0, 0xE934A84ADB052768ULL },
116             { 1, PRIME32, 0x5014607643A9B4C3ULL },
117             { 4, 0, 0x9136A0DCA57457EEULL },
118             { 14, 0, 0x8282DCC4994E35C8ULL },
119             { 14, PRIME32, 0xC3BD6BF63DEB6DF0ULL },
120             { 222, 0, 0xB641AE8CB691C174ULL },
121             { 222, PRIME32, 0x20CB8AB7AE10C14AULL }
122             };
123             /*
124             * XXH3:
125             * Due to being a more complex hash function with specializations for certain
126             * lengths, a more extensive test is used for XXH3.
127             */
128              
129             /* XXH3_64bits, seeded */
130             static const XSUM_testdata64_t XSUM_XXH3_testdata[] = {
131             { 0, 0, 0x2D06800538D394C2ULL }, /* empty string */
132             { 0, PRIME64, 0xA8A6B918B2F0364AULL }, /* empty string */
133             { 1, 0, 0xC44BDFF4074EECDBULL }, /* 1 - 3 */
134             { 1, PRIME64, 0x032BE332DD766EF8ULL }, /* 1 - 3 */
135             { 6, 0, 0x27B56A84CD2D7325ULL }, /* 4 - 8 */
136             { 6, PRIME64, 0x84589C116AB59AB9ULL }, /* 4 - 8 */
137             { 12, 0, 0xA713DAF0DFBB77E7ULL }, /* 9 - 16 */
138             { 12, PRIME64, 0xE7303E1B2336DE0EULL }, /* 9 - 16 */
139             { 24, 0, 0xA3FE70BF9D3510EBULL }, /* 17 - 32 */
140             { 24, PRIME64, 0x850E80FC35BDD690ULL }, /* 17 - 32 */
141             { 48, 0, 0x397DA259ECBA1F11ULL }, /* 33 - 64 */
142             { 48, PRIME64, 0xADC2CBAA44ACC616ULL }, /* 33 - 64 */
143             { 80, 0, 0xBCDEFBBB2C47C90AULL }, /* 65 - 96 */
144             { 80, PRIME64, 0xC6DD0CB699532E73ULL }, /* 65 - 96 */
145             { 195, 0, 0xCD94217EE362EC3AULL }, /* 129-240 */
146             { 195, PRIME64, 0xBA68003D370CB3D9ULL }, /* 129-240 */
147              
148             { 403, 0, 0xCDEB804D65C6DEA4ULL }, /* one block, last stripe is overlapping */
149             { 403, PRIME64, 0x6259F6ECFD6443FDULL }, /* one block, last stripe is overlapping */
150             { 512, 0, 0x617E49599013CB6BULL }, /* one block, finishing at stripe boundary */
151             { 512, PRIME64, 0x3CE457DE14C27708ULL }, /* one block, finishing at stripe boundary */
152             { 2048, 0, 0xDD59E2C3A5F038E0ULL }, /* 2 blocks, finishing at block boundary */
153             { 2048, PRIME64, 0x66F81670669ABABCULL }, /* 2 blocks, finishing at block boundary */
154             { 2240, 0, 0x6E73A90539CF2948ULL }, /* 3 blocks, finishing at stripe boundary */
155             { 2240, PRIME64, 0x757BA8487D1B5247ULL }, /* 3 blocks, finishing at stripe boundary */
156             { 2367, 0, 0xCB37AEB9E5D361EDULL }, /* 3 blocks, last stripe is overlapping */
157             { 2367, PRIME64, 0xD2DB3415B942B42AULL } /* 3 blocks, last stripe is overlapping */
158             };
159             /* XXH3_64bits, custom secret */
160             static const XSUM_testdata64_t XSUM_XXH3_withSecret_testdata[] = {
161             { 0, 0, 0x3559D64878C5C66CULL }, /* empty string */
162             { 1, 0, 0x8A52451418B2DA4DULL }, /* 1 - 3 */
163             { 6, 0, 0x82C90AB0519369ADULL }, /* 4 - 8 */
164             { 12, 0, 0x14631E773B78EC57ULL }, /* 9 - 16 */
165             { 24, 0, 0xCDD5542E4A9D9FE8ULL }, /* 17 - 32 */
166             { 48, 0, 0x33ABD54D094B2534ULL }, /* 33 - 64 */
167             { 80, 0, 0xE687BA1684965297ULL }, /* 65 - 96 */
168             { 195, 0, 0xA057273F5EECFB20ULL }, /* 129-240 */
169              
170             { 403, 0, 0x14546019124D43B8ULL }, /* one block, last stripe is overlapping */
171             { 512, 0, 0x7564693DD526E28DULL }, /* one block, finishing at stripe boundary */
172             { 2048, 0, 0xD32E975821D6519FULL }, /* >= 2 blodcks, at least one scrambling */
173             { 2367, 0, 0x293FA8E5173BB5E7ULL }, /* >= 2 blocks, at least one scrambling, last stripe unaligned */
174              
175             { 64*10*3, 0, 0x751D2EC54BC6038BULL } /* exactly 3 full blocks, not a multiple of 256 */
176             };
177             /* XXH3_128bits, seeded */
178             static const XSUM_testdata128_t XSUM_XXH128_testdata[] = {
179             { 0, 0, { 0x6001C324468D497FULL, 0x99AA06D3014798D8ULL } }, /* empty string */
180             { 0, PRIME32, { 0x5444F7869C671AB0ULL, 0x92220AE55E14AB50ULL } }, /* empty string */
181             { 1, 0, { 0xC44BDFF4074EECDBULL, 0xA6CD5E9392000F6AULL } }, /* 1 - 3 */
182             { 1, PRIME32, { 0xB53D5557E7F76F8DULL, 0x89B99554BA22467CULL } }, /* 1 - 3 */
183             { 6, 0, { 0x3E7039BDDA43CFC6ULL, 0x082AFE0B8162D12AULL } }, /* 4 - 8 */
184             { 6, PRIME32, { 0x269D8F70BE98856EULL, 0x5A865B5389ABD2B1ULL } }, /* 4 - 8 */
185             { 12, 0, { 0x061A192713F69AD9ULL, 0x6E3EFD8FC7802B18ULL } }, /* 9 - 16 */
186             { 12, PRIME32, { 0x9BE9F9A67F3C7DFBULL, 0xD7E09D518A3405D3ULL } }, /* 9 - 16 */
187             { 24, 0, { 0x1E7044D28B1B901DULL, 0x0CE966E4678D3761ULL } }, /* 17 - 32 */
188             { 24, PRIME32, { 0xD7304C54EBAD40A9ULL, 0x3162026714A6A243ULL } }, /* 17 - 32 */
189             { 48, 0, { 0xF942219AED80F67BULL, 0xA002AC4E5478227EULL } }, /* 33 - 64 */
190             { 48, PRIME32, { 0x7BA3C3E453A1934EULL, 0x163ADDE36C072295ULL } }, /* 33 - 64 */
191             { 81, 0, { 0x5E8BAFB9F95FB803ULL, 0x4952F58181AB0042ULL } }, /* 65 - 96 */
192             { 81, PRIME32, { 0x703FBB3D7A5F755CULL, 0x2724EC7ADC750FB6ULL } }, /* 65 - 96 */
193             { 222, 0, { 0xF1AEBD597CEC6B3AULL, 0x337E09641B948717ULL } }, /* 129-240 */
194             { 222, PRIME32, { 0xAE995BB8AF917A8DULL, 0x91820016621E97F1ULL } }, /* 129-240 */
195              
196             { 403, 0, { 0xCDEB804D65C6DEA4ULL, 0x1B6DE21E332DD73DULL } }, /* one block, last stripe is overlapping */
197             { 403, PRIME64, { 0x6259F6ECFD6443FDULL, 0xBED311971E0BE8F2ULL } }, /* one block, last stripe is overlapping */
198             { 512, 0, { 0x617E49599013CB6BULL, 0x18D2D110DCC9BCA1ULL } }, /* one block, finishing at stripe boundary */
199             { 512, PRIME64, { 0x3CE457DE14C27708ULL, 0x925D06B8EC5B8040ULL } }, /* one block, finishing at stripe boundary */
200             { 2048, 0, { 0xDD59E2C3A5F038E0ULL, 0xF736557FD47073A5ULL } }, /* 2 blocks, finishing at block boundary */
201             { 2048, PRIME32, { 0x230D43F30206260BULL, 0x7FB03F7E7186C3EAULL } }, /* 2 blocks, finishing at block boundary */
202             { 2240, 0, { 0x6E73A90539CF2948ULL, 0xCCB134FBFA7CE49DULL } }, /* 3 blocks, finishing at stripe boundary */
203             { 2240, PRIME32, { 0xED385111126FBA6FULL, 0x50A1FE17B338995FULL } }, /* 3 blocks, finishing at stripe boundary */
204             { 2367, 0, { 0xCB37AEB9E5D361EDULL, 0xE89C0F6FF369B427ULL } }, /* 3 blocks, last stripe is overlapping */
205             { 2367, PRIME32, { 0x6F5360AE69C2F406ULL, 0xD23AAE4B76C31ECBULL } } /* 3 blocks, last stripe is overlapping */
206             };
207              
208             /* XXH128, custom secret */
209             static const XSUM_testdata128_t XSUM_XXH128_withSecret_testdata[] = {
210             { 0, 0, { 0x005923CCEECBE8AEULL, 0x5F70F4EA232F1D38ULL } }, /* empty string */
211             { 1, 0, { 0x8A52451418B2DA4DULL, 0x3A66AF5A9819198EULL } }, /* 1 - 3 */
212             { 6, 0, { 0x0B61C8ACA7D4778FULL, 0x376BD91B6432F36DULL } }, /* 4 - 8 */
213             { 12, 0, { 0xAF82F6EBA263D7D8ULL, 0x90A3C2D839F57D0FULL } } /* 9 - 16 */
214             };
215              
216             static const XSUM_testdata_sample_t XSUM_XXH3_generateSecret_testdata[] = {
217             { 0, { 0xB8, 0x26, 0x83, 0x7E } },
218             { 1, { 0xA6, 0x16, 0x06, 0x7B } },
219             { XXH3_SECRET_SIZE_MIN - 1, { 0xDA, 0x2A, 0x12, 0x11 } },
220             { XXH3_SECRET_DEFAULT_SIZE + 500, { 0x7E, 0x48, 0x0C, 0xA7 } }
221             };
222              
223 0           static void XSUM_checkResult32(XXH32_hash_t r1, XXH32_hash_t r2)
224             {
225             static int nbTests = 1;
226 0 0         if (r1!=r2) {
227 0           XSUM_log("\rError: 32-bit hash test %i: Internal sanity check failed!\n", nbTests);
228 0           XSUM_log("\rGot 0x%08X, expected 0x%08X.\n", (unsigned)r1, (unsigned)r2);
229 0           XSUM_log("\rNote: If you modified the hash functions, make sure to either update the values\n"
230             "or temporarily recompile with XSUM_NO_TESTS=1.\n");
231 0           exit(1);
232             }
233 0           nbTests++;
234 0           }
235              
236 0           static void XSUM_checkResult64(XXH64_hash_t r1, XXH64_hash_t r2)
237             {
238             static int nbTests = 1;
239 0 0         if (r1!=r2) {
240 0           XSUM_log("\rError: 64-bit hash test %i: Internal sanity check failed!\n", nbTests);
241 0           XSUM_log("\rGot 0x%08X%08XULL, expected 0x%08X%08XULL.\n",
242 0           (unsigned)(r1>>32), (unsigned)r1, (unsigned)(r2>>32), (unsigned)r2);
243 0           XSUM_log("\rNote: If you modified the hash functions, make sure to either update the values\n"
244             "or temporarily recompile with XSUM_NO_TESTS=1.\n");
245 0           exit(1);
246             }
247 0           nbTests++;
248 0           }
249              
250 0           static void XSUM_checkResult128(XXH128_hash_t r1, XXH128_hash_t r2)
251             {
252             static int nbTests = 1;
253 0 0         if ((r1.low64 != r2.low64) || (r1.high64 != r2.high64)) {
    0          
254 0           XSUM_log("\rError: 128-bit hash test %i: Internal sanity check failed.\n", nbTests);
255 0           XSUM_log("\rGot { 0x%08X%08XULL, 0x%08X%08XULL }, expected { 0x%08X%08XULL, 0x%08X%08XULL } \n",
256 0           (unsigned)(r1.low64>>32), (unsigned)r1.low64, (unsigned)(r1.high64>>32), (unsigned)r1.high64,
257 0           (unsigned)(r2.low64>>32), (unsigned)r2.low64, (unsigned)(r2.high64>>32), (unsigned)r2.high64 );
258 0           XSUM_log("\rNote: If you modified the hash functions, make sure to either update the values\n"
259             "or temporarily recompile with XSUM_NO_TESTS=1.\n");
260 0           exit(1);
261             }
262 0           nbTests++;
263 0           }
264              
265              
266 0           static void XSUM_testXXH32(const void* data, const XSUM_testdata32_t* testData)
267             {
268 0           XXH32_state_t *state = XXH32_createState();
269             size_t pos;
270              
271 0           size_t len = testData->len;
272 0           XSUM_U32 seed = testData->seed;
273 0           XSUM_U32 Nresult = testData->Nresult;
274              
275 0 0         if (len == 0) {
276             data = NULL;
277             } else {
278 0 0         assert(data != NULL);
279             }
280              
281 0 0         assert(state != NULL);
282              
283 0           XSUM_checkResult32(XXH32(data, len, seed), Nresult);
284              
285 0           (void)XXH32_reset(state, seed);
286 0           (void)XXH32_update(state, data, len);
287 0           XSUM_checkResult32(XXH32_digest(state), Nresult);
288              
289 0           (void)XXH32_reset(state, seed);
290 0 0         for (pos=0; pos
291 0           (void)XXH32_update(state, ((const char*)data)+pos, 1);
292 0           XSUM_checkResult32(XXH32_digest(state), Nresult);
293 0           XXH32_freeState(state);
294 0           }
295              
296 0           static void XSUM_testXXH64(const void* data, const XSUM_testdata64_t* testData)
297             {
298 0           XXH64_state_t *state = XXH64_createState();
299             size_t pos;
300              
301 0           size_t len = (size_t)testData->len;
302 0           XSUM_U64 seed = testData->seed;
303 0           XSUM_U64 Nresult = testData->Nresult;
304              
305 0 0         if (len == 0) {
306             data = NULL;
307             } else {
308 0 0         assert(data != NULL);
309             }
310              
311 0 0         assert(state != NULL);
312              
313 0           XSUM_checkResult64(XXH64(data, len, seed), Nresult);
314              
315 0           (void)XXH64_reset(state, seed);
316 0           (void)XXH64_update(state, data, len);
317 0           XSUM_checkResult64(XXH64_digest(state), Nresult);
318              
319 0           (void)XXH64_reset(state, seed);
320 0 0         for (pos=0; pos
321 0           (void)XXH64_update(state, ((const char*)data)+pos, 1);
322 0           XSUM_checkResult64(XXH64_digest(state), Nresult);
323 0           XXH64_freeState(state);
324 0           }
325              
326             /*
327             * Used to get "random" (but actually 100% reproducible) lengths for
328             * XSUM_XXH3_randomUpdate.
329             */
330             static XSUM_U32 XSUM_rand(void)
331             {
332             static XSUM_U64 seed = PRIME32;
333 0           seed *= PRIME64;
334 0           return (XSUM_U32)(seed >> 40);
335             }
336              
337             /*
338             * Technically, XXH3_64bits_update is identical to XXH3_128bits_update as of
339             * v0.8.0, but we treat them as separate.
340             */
341             typedef XXH_errorcode (*XSUM_XXH3_update_t)(XXH3_state_t* state, const void* input, size_t length);
342              
343             /*
344             * Runs the passed XXH3_update variant on random lengths. This is to test the
345             * more complex logic of the update function, catching bugs like this one:
346             * https://github.com/Cyan4973/xxHash/issues/378
347             */
348 0           static void XSUM_XXH3_randomUpdate(XXH3_state_t* state, const void* data,
349             size_t len, XSUM_XXH3_update_t update_fn)
350             {
351             size_t p = 0;
352 0 0         while (p < len) {
353 0           size_t const modulo = len > 2 ? len : 2;
354 0           size_t l = (size_t)(XSUM_rand()) % modulo;
355 0 0         if (p + l > len) l = len - p;
356 0           (void)update_fn(state, (const char*)data+p, l);
357 0           p += l;
358             }
359 0           }
360              
361 0           static void XSUM_testXXH3(const void* data, const XSUM_testdata64_t* testData)
362             {
363 0           size_t len = testData->len;
364 0           XSUM_U64 seed = testData->seed;
365 0           XSUM_U64 Nresult = testData->Nresult;
366 0 0         if (len == 0) {
367             data = NULL;
368             } else {
369 0 0         assert(data != NULL);
370             }
371 0           { XSUM_U64 const Dresult = XXH3_64bits_withSeed(data, len, seed);
372 0           XSUM_checkResult64(Dresult, Nresult);
373             }
374              
375             /* check that the no-seed variant produces same result as seed==0 */
376 0 0         if (seed == 0) {
377 0           XSUM_U64 const Dresult = XXH3_64bits(data, len);
378 0           XSUM_checkResult64(Dresult, Nresult);
379             }
380              
381             /* streaming API test */
382 0           { XXH3_state_t* const state = XXH3_createState();
383 0 0         assert(state != NULL);
384             /* single ingestion */
385 0           (void)XXH3_64bits_reset_withSeed(state, seed);
386 0           (void)XXH3_64bits_update(state, data, len);
387 0           XSUM_checkResult64(XXH3_64bits_digest(state), Nresult);
388              
389             /* random ingestion */
390 0           (void)XXH3_64bits_reset_withSeed(state, seed);
391 0           XSUM_XXH3_randomUpdate(state, data, len, &XXH3_64bits_update);
392 0           XSUM_checkResult64(XXH3_64bits_digest(state), Nresult);
393              
394             /* byte by byte ingestion */
395             { size_t pos;
396 0           (void)XXH3_64bits_reset_withSeed(state, seed);
397 0 0         for (pos=0; pos
398 0           (void)XXH3_64bits_update(state, ((const char*)data)+pos, 1);
399 0           XSUM_checkResult64(XXH3_64bits_digest(state), Nresult);
400             }
401 0           XXH3_freeState(state);
402             }
403 0           }
404              
405 0           static void XSUM_testXXH3_withSecret(const void* data, const void* secret,
406             size_t secretSize, const XSUM_testdata64_t* testData)
407             {
408 0           size_t len = (size_t)testData->len;
409 0           XSUM_U64 Nresult = testData->Nresult;
410              
411 0 0         if (len == 0) {
412             data = NULL;
413             } else {
414 0 0         assert(data != NULL);
415             }
416 0           { XSUM_U64 const Dresult = XXH3_64bits_withSecret(data, len, secret, secretSize);
417 0           XSUM_checkResult64(Dresult, Nresult);
418             }
419              
420             /* streaming API test */
421 0           { XXH3_state_t *state = XXH3_createState();
422 0 0         assert(state != NULL);
423 0           (void)XXH3_64bits_reset_withSecret(state, secret, secretSize);
424 0           (void)XXH3_64bits_update(state, data, len);
425 0           XSUM_checkResult64(XXH3_64bits_digest(state), Nresult);
426              
427             /* random ingestion */
428 0           (void)XXH3_64bits_reset_withSecret(state, secret, secretSize);
429 0           XSUM_XXH3_randomUpdate(state, data, len, &XXH3_64bits_update);
430 0           XSUM_checkResult64(XXH3_64bits_digest(state), Nresult);
431              
432             /* byte by byte ingestion */
433             { size_t pos;
434 0           (void)XXH3_64bits_reset_withSecret(state, secret, secretSize);
435 0 0         for (pos=0; pos
436 0           (void)XXH3_64bits_update(state, ((const char*)data)+pos, 1);
437 0           XSUM_checkResult64(XXH3_64bits_digest(state), Nresult);
438             }
439 0           XXH3_freeState(state);
440             }
441 0           }
442              
443 0           static void XSUM_testXXH128(const void* data, const XSUM_testdata128_t* testData)
444             {
445 0           size_t len = (size_t)testData->len;
446 0           XSUM_U64 seed = testData->seed;
447 0           XXH128_hash_t const Nresult = testData->Nresult;
448 0 0         if (len == 0) {
449             data = NULL;
450             } else {
451 0 0         assert(data != NULL);
452             }
453              
454 0           { XXH128_hash_t const Dresult = XXH3_128bits_withSeed(data, len, seed);
455 0           XSUM_checkResult128(Dresult, Nresult);
456             }
457              
458             /* check that XXH128() is identical to XXH3_128bits_withSeed() */
459 0           { XXH128_hash_t const Dresult2 = XXH128(data, len, seed);
460 0           XSUM_checkResult128(Dresult2, Nresult);
461             }
462              
463             /* check that the no-seed variant produces same result as seed==0 */
464 0 0         if (seed == 0) {
465 0           XXH128_hash_t const Dresult = XXH3_128bits(data, len);
466 0           XSUM_checkResult128(Dresult, Nresult);
467             }
468              
469             /* streaming API test */
470 0           { XXH3_state_t *state = XXH3_createState();
471 0 0         assert(state != NULL);
472              
473             /* single ingestion */
474 0           (void)XXH3_128bits_reset_withSeed(state, seed);
475 0           (void)XXH3_128bits_update(state, data, len);
476 0           XSUM_checkResult128(XXH3_128bits_digest(state), Nresult);
477              
478             /* random ingestion */
479 0           (void)XXH3_128bits_reset_withSeed(state, seed);
480 0           XSUM_XXH3_randomUpdate(state, data, len, &XXH3_128bits_update);
481 0           XSUM_checkResult128(XXH3_128bits_digest(state), Nresult);
482              
483             /* byte by byte ingestion */
484             { size_t pos;
485 0           (void)XXH3_128bits_reset_withSeed(state, seed);
486 0 0         for (pos=0; pos
487 0           (void)XXH3_128bits_update(state, ((const char*)data)+pos, 1);
488 0           XSUM_checkResult128(XXH3_128bits_digest(state), Nresult);
489             }
490 0           XXH3_freeState(state);
491             }
492 0           }
493              
494 0           static void XSUM_testXXH128_withSecret(const void* data, const void* secret, size_t secretSize, const XSUM_testdata128_t* testData)
495             {
496 0           size_t len = testData->len;
497 0           XXH128_hash_t Nresult = testData->Nresult;
498 0 0         if (len == 0) {
499             data = NULL;
500 0 0         } else if (len>0) {
501 0 0         assert(data != NULL);
502             }
503 0           { XXH128_hash_t const Dresult = XXH3_128bits_withSecret(data, len, secret, secretSize);
504 0           XSUM_checkResult128(Dresult, Nresult);
505             }
506              
507             /* streaming API test */
508 0           { XXH3_state_t* const state = XXH3_createState();
509 0 0         assert(state != NULL);
510 0           (void)XXH3_128bits_reset_withSecret(state, secret, secretSize);
511 0           (void)XXH3_128bits_update(state, data, len);
512 0           XSUM_checkResult128(XXH3_128bits_digest(state), Nresult);
513              
514             /* random ingestion */
515 0           (void)XXH3_128bits_reset_withSecret(state, secret, secretSize);
516 0           XSUM_XXH3_randomUpdate(state, data, len, &XXH3_128bits_update);
517 0           XSUM_checkResult128(XXH3_128bits_digest(state), Nresult);
518              
519             /* byte by byte ingestion */
520             { size_t pos;
521 0           (void)XXH3_128bits_reset_withSecret(state, secret, secretSize);
522 0 0         for (pos=0; pos
523 0           (void)XXH3_128bits_update(state, ((const char*)data)+pos, 1);
524 0           XSUM_checkResult128(XXH3_128bits_digest(state), Nresult);
525             }
526 0           XXH3_freeState(state);
527             }
528 0           }
529              
530 0           static void XSUM_testSecretGenerator(const void* customSeed, const XSUM_testdata_sample_t* testData)
531             {
532             static int nbTests = 1;
533 0           const int sampleIndex[SECRET_SAMPLE_NBBYTES] = { 0, 62, 131, 191};
534 0           XSUM_U8 secretBuffer[XXH3_SECRET_DEFAULT_SIZE] = {0};
535             XSUM_U8 samples[SECRET_SAMPLE_NBBYTES];
536             int i;
537              
538 0           XXH3_generateSecret(secretBuffer, customSeed, testData->len);
539 0 0         for (i=0; i
540 0           samples[i] = secretBuffer[sampleIndex[i]];
541             }
542 0 0         if (memcmp(samples, testData->byte, sizeof(testData->byte))) {
543 0           XSUM_log("\rError: Secret generation test %i: Internal sanity check failed. \n", nbTests);
544 0           XSUM_log("\rGot { 0x%02X, 0x%02X, 0x%02X, 0x%02X }, expected { 0x%02X, 0x%02X, 0x%02X, 0x%02X } \n",
545 0           samples[0], samples[1], samples[2], samples[3],
546 0           testData->byte[0], testData->byte[1], testData->byte[2], testData->byte[3] );
547 0           exit(1);
548             }
549 0           nbTests++;
550 0           }
551              
552             /*!
553             * XSUM_sanityCheck():
554             * Runs a sanity check before the benchmark.
555             *
556             * Exits on an incorrect output.
557             */
558 0           XSUM_API void XSUM_sanityCheck(void)
559             {
560             size_t i;
561             #define SANITY_BUFFER_SIZE 2367
562             XSUM_U8 sanityBuffer[SANITY_BUFFER_SIZE];
563             const void* const secret = sanityBuffer + 7;
564             const size_t secretSize = XXH3_SECRET_SIZE_MIN + 11;
565             assert(sizeof(sanityBuffer) >= 7 + secretSize);
566              
567 0           XSUM_fillTestBuffer(sanityBuffer, sizeof(sanityBuffer));
568              
569             /* XXH32 */
570 0 0         for (i = 0; i < (sizeof(XSUM_XXH32_testdata)/sizeof(XSUM_XXH32_testdata[0])); i++) {
571 0           XSUM_testXXH32(sanityBuffer, &XSUM_XXH32_testdata[i]);
572             }
573             /* XXH64 */
574 0 0         for (i = 0; i < (sizeof(XSUM_XXH64_testdata)/sizeof(XSUM_XXH64_testdata[0])); i++) {
575 0           XSUM_testXXH64(sanityBuffer, &XSUM_XXH64_testdata[i]);
576             }
577             /* XXH3_64bits, seeded */
578 0 0         for (i = 0; i < (sizeof(XSUM_XXH3_testdata)/sizeof(XSUM_XXH3_testdata[0])); i++) {
579 0           XSUM_testXXH3(sanityBuffer, &XSUM_XXH3_testdata[i]);
580             }
581             /* XXH3_64bits, custom secret */
582 0 0         for (i = 0; i < (sizeof(XSUM_XXH3_withSecret_testdata)/sizeof(XSUM_XXH3_withSecret_testdata[0])); i++) {
583 0           XSUM_testXXH3_withSecret(sanityBuffer, secret, secretSize, &XSUM_XXH3_withSecret_testdata[i]);
584             }
585             /* XXH128 */
586 0 0         for (i = 0; i < (sizeof(XSUM_XXH128_testdata)/sizeof(XSUM_XXH128_testdata[0])); i++) {
587 0           XSUM_testXXH128(sanityBuffer, &XSUM_XXH128_testdata[i]);
588             }
589             /* XXH128 with custom Secret */
590 0 0         for (i = 0; i < (sizeof(XSUM_XXH128_withSecret_testdata)/sizeof(XSUM_XXH128_withSecret_testdata[0])); i++) {
591 0           XSUM_testXXH128_withSecret(sanityBuffer, secret, secretSize, &XSUM_XXH128_withSecret_testdata[i]);
592             }
593             /* secret generator */
594 0 0         for (i = 0; i < (sizeof(XSUM_XXH3_generateSecret_testdata)/sizeof(XSUM_XXH3_generateSecret_testdata[0])); i++) {
595 0           XSUM_testSecretGenerator(sanityBuffer, &XSUM_XXH3_generateSecret_testdata[i]);
596             }
597              
598 0           XSUM_logVerbose(3, "\r%70s\r", ""); /* Clean display line */
599 0           XSUM_logVerbose(3, "Sanity check -- all tests ok\n");
600 0           }
601              
602             #endif /* !XSUM_NO_TESTS */