From: Yves Orton Date: Mon, 10 Dec 2012 07:36:43 +0000 (+0100) Subject: add a hardened one-at-a-time hash variant X-Git-Tag: upstream/5.20.0~3791 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b1300a738fa7f7665aa35a1f9347cf71c52a5b6e;p=platform%2Fupstream%2Fperl.git add a hardened one-at-a-time hash variant Mix in additional randomness into the final value. --- diff --git a/hv_func.h b/hv_func.h index fdb4ad8..df39808 100644 --- a/hv_func.h +++ b/hv_func.h @@ -18,12 +18,13 @@ || defined(PERL_HASH_FUNC_SUPERFAST) \ || defined(PERL_HASH_FUNC_MURMUR3) \ || defined(PERL_HASH_FUNC_ONE_AT_A_TIME) \ + || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) \ || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_OLD) \ ) #ifdef HAS_QUAD #define PERL_HASH_FUNC_SIPHASH #else -#define PERL_HASH_FUNC_ONE_AT_A_TIME +#define PERL_HASH_FUNC_ONE_AT_A_TIME_HARD #endif #endif @@ -47,6 +48,10 @@ # define PERL_HASH_FUNC "SDBM" # define PERL_HASH_SEED_BYTES 4 # define PERL_HASH(hash,str,len) (hash)= S_perl_hash_sdbm(PERL_HASH_SEED,(U8*)(str),(len)) +#elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) +# define PERL_HASH_FUNC "ONE_AT_A_TIME_HARD" +# define PERL_HASH_SEED_BYTES 8 +# define PERL_HASH(hash,str,len) (hash)= S_perl_hash_one_at_a_time_hard(PERL_HASH_SEED,(U8*)(str),(len)) #elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME) # define PERL_HASH_FUNC "ONE_AT_A_TIME" # define PERL_HASH_SEED_BYTES 4 @@ -460,9 +465,11 @@ S_perl_hash_sdbm(const unsigned char * const seed, const unsigned char *str, con } -/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins +/* This is the "One-at-a-Time" algorithm by Bob Jenkins * from requirements by Colin Plumb. - * (http://burtleburtle.net/bob/hash/doobs.html) */ + * (http://burtleburtle.net/bob/hash/doobs.html) + * With seed/len tweak. + * */ PERL_STATIC_INLINE U32 S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) { const unsigned char * const end = (const unsigned char *)str + len; @@ -477,6 +484,42 @@ S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char return (hash + (hash << 15)); } +/* Derived from "One-at-a-Time" algorithm by Bob Jenkins */ +PERL_STATIC_INLINE U32 +S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned char *str, const STRLEN len) { + const unsigned char * const end = (const unsigned char *)str + len; + U32 hash = *((U32*)seed) + len; + + while (str < end) { + hash += (hash << 10); + hash ^= (hash >> 6); + hash += *str++; + } + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[4]; + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[5]; + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[6]; + + hash += (hash << 10); + hash ^= (hash >> 6); + hash += seed[7]; + + hash += (hash << 10); + hash ^= (hash >> 6); + + hash += (hash << 3); + hash ^= (hash >> 11); + return (hash + (hash << 15)); +} + PERL_STATIC_INLINE U32 S_perl_hash_old_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) { const unsigned char * const end = (const unsigned char *)str + len;