completed midsize (129-240)

including streaming and self-tests
This commit is contained in:
Yann Collet 2019-06-17 14:16:52 -07:00
parent 93f114c261
commit 35d1e2fd7e
3 changed files with 32 additions and 42 deletions

47
xxh3.h
View File

@ -153,9 +153,9 @@ XXH_FORCE_INLINE U64x2 XXH_vsxMultEven(U32x4 a, U32x4 b) {
* XXH3 default settings
* ========================================== */
#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH_SECRET_SIZE_MIN */
#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
#if (XXH_SECRET_DEFAULT_SIZE < XXH_SECRET_SIZE_MIN)
#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN)
# error "default keyset is not large enough"
#endif
@ -706,7 +706,7 @@ XXH3_hashLong_internal_loop( U64* restrict acc,
size_t n;
assert(secretSize >= XXH_SECRET_SIZE_MIN);
assert(secretSize >= XXH3_SECRET_SIZE_MIN);
for (n = 0; n < nb_blocks; n++) {
XXH3_accumulate(acc, (const char*)data + n*block_len, secret, nb_rounds);
@ -836,7 +836,7 @@ XXH3_len_17to128_64b(const void* restrict data, size_t len, const void* restrict
const BYTE* const p = (const BYTE*)data;
const char* const key = (const char*)secret;
assert(secretSize >= XXH_SECRET_SIZE_MIN); (void)secretSize;
assert(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
assert(16 < len && len <= 128);
{ U64 acc = len * PRIME64_1;
@ -865,7 +865,7 @@ XXH3_len_129to240_64b(const void* restrict data, size_t len, const void* restric
const BYTE* const p = (const BYTE*)data;
const char* const key = (const char*)secret;
assert(secretSize >= XXH_SECRET_SIZE_MIN); (void)secretSize;
assert(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
assert(128 < len && len <= 240);
#define XXH3_MIDSIZE_STARTOFFSET 3
@ -883,49 +883,35 @@ XXH3_len_129to240_64b(const void* restrict data, size_t len, const void* restric
acc += XXH3_mix16B(p+(16*i), key+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
}
/* last bytes */
acc += XXH3_mix16B(p + len - 16, key + XXH_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
acc += XXH3_mix16B(p + len - 16, key + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
return XXH3_avalanche(acc);
}
}
#define XXH3_MIDSIZE_MAX 240
XXH_FORCE_INLINE XXH64_hash_t
XXH3_len_0to240_64b(const void* restrict data, size_t len, const void* restrict secret, size_t secretSize, XXH64_hash_t seed)
{
assert(len <= XXH3_MIDSIZE_MAX);
if (len <= 16) return XXH3_len_0to16_64b(data, len, secret, seed);
if (len <= 128) return XXH3_len_17to128_64b(data, len, secret, sizeof(secretSize), seed);
return XXH3_len_129to240_64b(data, len, secret, sizeof(secretSize), seed);
}
/* === Public entry point === */
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len)
{
#if 0
if (len <= 16) return XXH3_len_0to16_64b(data, len, kSecret, 0);
if (len <= 128) return XXH3_len_17to128_64b(data, len, kSecret, sizeof(kSecret), 0);
if (len <= 240) return XXH3_len_129to240_64b(data, len, kSecret, sizeof(kSecret), 0);
#else
if (len <= XXH3_MIDSIZE_MAX)
return XXH3_len_0to240_64b(data, len, kSecret, sizeof(kSecret), 0);
#endif
return XXH3_hashLong_64b_defaultSecret(data, len);
}
XXH_PUBLIC_API XXH64_hash_t
XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize)
{
assert(secretSize >= XXH_SECRET_SIZE_MIN);
assert(((size_t)secret % 8) == 0);
assert(secretSize >= XXH3_SECRET_SIZE_MIN);
/* if an action must be taken should `secret` conditions not be respected,
* it should be done here.
* For now, it's a contract pre-condition.
* Adding a check and a branch here would cost performance at every hash */
if (len <= 16) return XXH3_len_0to16_64b(data, len, secret, 0);
if (len > 128) return XXH3_hashLong_64b_withSecret(data, len, secret, secretSize);
return XXH3_len_17to128_64b(data, len, secret, secretSize, 0);
if (len <= 128) return XXH3_len_17to128_64b(data, len, secret, secretSize, 0);
if (len <= 240) return XXH3_len_129to240_64b(data, len, secret, secretSize, 0);
return XXH3_hashLong_64b_withSecret(data, len, secret, secretSize);
}
XXH_PUBLIC_API XXH64_hash_t
@ -938,8 +924,9 @@ XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed)
* Maybe do it into XXH3_hashLong_64b_withSeed() instead,
* since that's where it matters */
if (len <= 16) return XXH3_len_0to16_64b(data, len, kSecret, seed);
if (len > 128) return XXH3_hashLong_64b_withSeed(data, len, seed);
return XXH3_len_17to128_64b(data, len, kSecret, sizeof(kSecret), seed);
if (len <= 128) return XXH3_len_17to128_64b(data, len, kSecret, sizeof(kSecret), seed);
if (len <= 240) return XXH3_len_129to240_64b(data, len, kSecret, sizeof(kSecret), seed);
return XXH3_hashLong_64b_withSeed(data, len, seed);
}
/* === XXH3 streaming === */
@ -979,7 +966,7 @@ XXH3_64bits_reset_internal(XXH3_state_t* statePtr,
statePtr->seed = seed;
assert(secret != NULL);
statePtr->secret = secret;
assert(secretSize >= XXH_SECRET_SIZE_MIN);
assert(secretSize >= XXH3_SECRET_SIZE_MIN);
statePtr->secretLimit = (XXH32_hash_t)(secretSize - STRIPE_LEN);
statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
}
@ -998,7 +985,7 @@ XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t
if (statePtr == NULL) return XXH_ERROR;
XXH3_64bits_reset_internal(statePtr, 0, secret, secretSize);
if (secret == NULL) return XXH_ERROR;
if (secretSize < XXH_SECRET_SIZE_MIN) return XXH_ERROR;
if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
return XXH_OK;
}
@ -1091,7 +1078,7 @@ XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
{
if (state->totalLen > XXH3_INTERNALBUFFER_SIZE) {
if (state->totalLen > XXH3_MIDSIZE_MAX) {
XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[ACC_NB];
memcpy(acc, state->acc, sizeof(acc)); /* digest locally, state remains unaltered, and can continue ingesting more data afterwards */
if (state->bufferedSize >= STRIPE_LEN) {
@ -1114,7 +1101,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
} }
return XXH3_mergeAccs(acc, (const char*)state->secret + XXH_SECRET_MERGEACCS_START, (U64)state->totalLen * PRIME64_1);
}
/* len <= XXH3_INTERNALBUFFER_SIZE : short code */
/* len <= XXH3_MIDSIZE_MAX : short code */
if (state->seed)
return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), state->secret, state->secretLimit + STRIPE_LEN);

View File

@ -400,13 +400,13 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);
/* XXH3_64bits_withSecret() :
* It's possible to provide any blob of bytes as a "secret" to generate the hash.
* This makes it more difficult for an external actor to prepare an intentional collision.
* The secret *must* be large enough (>= XXH_SECRET_SIZE_MIN).
* The secret *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
* It should consist of random bytes.
* Avoid repeating same character, and especially avoid swathes of \0.
* Avoid repeating sequences of bytes within the secret.
* Failure to respect these conditions will result in a bad quality hash.
*/
#define XXH_SECRET_SIZE_MIN 136
#define XXH3_SECRET_SIZE_MIN 136
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
/* XXH3_64bits_withSeed() :
@ -432,8 +432,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
typedef struct XXH3_state_s XXH3_state_t;
#define XXH3_SECRET_DEFAULT_SIZE 192 /* minimum XXH_SECRET_SIZE_MIN */
#define XXH3_INTERNALBUFFER_SIZE 128
#define XXH3_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
#define XXH3_INTERNALBUFFER_SIZE 256
struct XXH3_state_s {
XXH_ALIGN(64) XXH64_hash_t acc[8];
XXH_ALIGN(64) char customSecret[XXH3_SECRET_DEFAULT_SIZE]; /* used to store a custom secret generated from the seed. Makes state larger. Design might change */
@ -469,7 +469,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
/* XXH3_64bits_reset_withSecret() :
* `secret` is referenced, and must outlive the hash streaming session.
* secretSize must be >= XXH_SECRET_SIZE_MIN.
* secretSize must be >= XXH3_SECRET_SIZE_MIN.
*/
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);

View File

@ -733,11 +733,13 @@ static void BMK_sanityCheck(void)
BMK_testXXH3(sanityBuffer, 80, prime64, 0xC9D55256965B7093ULL); /* 65 - 96 */
BMK_testXXH3(sanityBuffer, 112, 0, 0xE43E5717A61D3759ULL); /* 97 -128 */
BMK_testXXH3(sanityBuffer, 112, prime64, 0x5A5F89A3FECE44A5ULL); /* 97 -128 */
BMK_testXXH3(sanityBuffer, 195, 0, 0x0F4A0BBE808382AEULL); /* 129-240 */
BMK_testXXH3(sanityBuffer, 195, prime64, 0x9DF94C96C46AF6CCULL); /* 129-240 */
BMK_testXXH3(sanityBuffer, 192, 0, 0x657FDAF1B5B85A98ULL); /* one block, finishing at stripe boundary */
BMK_testXXH3(sanityBuffer, 192, prime64, 0xCE739A124E5395BFULL); /* one block, finishing at stripe boundary */
BMK_testXXH3(sanityBuffer, 222, 0, 0x9D1CEA1C7134C072ULL); /* one block, last stripe is overlapping */
BMK_testXXH3(sanityBuffer, 222, prime64, 0x71CFC4572F8FCD9DULL); /* one block, last stripe is overlapping */
BMK_testXXH3(sanityBuffer, 384, 0, 0x45CCC94C86BE739FULL); /* one block, finishing at stripe boundary */
BMK_testXXH3(sanityBuffer, 384, prime64, 0x79C743D8B9A54FBCULL); /* one block, finishing at stripe boundary */
BMK_testXXH3(sanityBuffer, 403, 0, 0x4834389B15D981E8ULL); /* one block, last stripe is overlapping */
BMK_testXXH3(sanityBuffer, 403, prime64, 0x85CE5DFFC7B07C87ULL); /* one block, last stripe is overlapping */
BMK_testXXH3(sanityBuffer,2048, 0, 0xEFEFD4449323CDD4ULL); /* 2 blocks, finishing at block boundary */
BMK_testXXH3(sanityBuffer,2048, prime64, 0x01C85E405ECA3F6EULL); /* 2 blocks, finishing at block boundary */
BMK_testXXH3(sanityBuffer,2240, 0, 0x998C0437486672C7ULL); /* 3 blocks, finishing at stripe boundary */
@ -746,7 +748,7 @@ static void BMK_sanityCheck(void)
BMK_testXXH3(sanityBuffer,2243, prime64, 0x96E051AB57F21FC8ULL); /* 3 blocks, last stripe is overlapping */
{ const void* const secret = sanityBuffer + 7;
const size_t secretSize = XXH_SECRET_SIZE_MIN + 11;
const size_t secretSize = XXH3_SECRET_SIZE_MIN + 11;
BMK_testXXH3_withSecret(NULL, 0, secret, secretSize, 0); /* zero-length hash is always 0 */
BMK_testXXH3_withSecret(sanityBuffer, 1, secret, secretSize, 0x420EAC06C004273FULL); /* 1 - 3 */
BMK_testXXH3_withSecret(sanityBuffer, 6, secret, secretSize, 0x5A90048A433D5017ULL); /* 6 - 8 */
@ -755,9 +757,10 @@ static void BMK_sanityCheck(void)
BMK_testXXH3_withSecret(sanityBuffer, 48, secret, secretSize, 0xA785256D9D65D514ULL); /* 33 - 64 */
BMK_testXXH3_withSecret(sanityBuffer, 80, secret, secretSize, 0x6F3053360D21BBB7ULL); /* 65 - 96 */
BMK_testXXH3_withSecret(sanityBuffer, 112, secret, secretSize, 0x560E82D25684154CULL); /* 97 -128 */
BMK_testXXH3_withSecret(sanityBuffer, 195, secret, secretSize, 0x08AD6AB5ACA1B218ULL); /* 129-240 */
BMK_testXXH3_withSecret(sanityBuffer, 192, secret, secretSize, 0x615B7F3B2DA09681ULL); /* one block, finishing at stripe boundary */
BMK_testXXH3_withSecret(sanityBuffer, 222, secret, secretSize, 0x6E5D78EEE071A11AULL); /* one block, last stripe is overlapping */
BMK_testXXH3_withSecret(sanityBuffer, 384, secret, secretSize, 0x9656E0F288042CB9ULL); /* one block, finishing at stripe boundary */
BMK_testXXH3_withSecret(sanityBuffer, 403, secret, secretSize, 0xFC3911BBA656DB58ULL); /* one block, last stripe is overlapping */
BMK_testXXH3_withSecret(sanityBuffer,2048, secret, secretSize, 0x2836B83880AD3C0CULL); /* > one block, at least one scrambling */
BMK_testXXH3_withSecret(sanityBuffer,2243, secret, secretSize, 0x3446E248A00CB44AULL); /* > one block, at least one scrambling, last stripe unaligned */
}