mirror of
https://github.com/Perl/perl5.git
synced 2026-01-26 08:38:23 +00:00
perl_siphash.h - add a 64 bit variant for testing, cleanup line endings
Scott Baker wanted a 64 bit general purpose hash function. Currently our Siphash implementation is optimized for use in the internal hash tables by having its state initialization separated from the main hash function. We have a 32 bit variant we use for testing that takes a seed and not a state, but our only 64 bit support has the seeding step split out. This patch exposes a seedable 64 bit function. Note, that Siphash *is* a 64 bit hash function, however historically we only use 32 bit hashes in our hash tables. The new variant we expose here basically just exposes the normal Siphash that most people would use. A follow up patch will add documentation.
This commit is contained in:
parent
82a05dc6fa
commit
eb5a17c893
117
perl_siphash.h
117
perl_siphash.h
@ -43,29 +43,29 @@ void S_perl_siphash_seed_state(const unsigned char * const seed_buf, unsigned ch
|
|||||||
PERL_STATIC_INLINE U64 \
|
PERL_STATIC_INLINE U64 \
|
||||||
FNC ## _with_state_64 \
|
FNC ## _with_state_64 \
|
||||||
(const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \
|
(const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \
|
||||||
{ \
|
{ \
|
||||||
const int left = inlen & 7; \
|
const int left = inlen & 7; \
|
||||||
const U8 *end = in + inlen - left; \
|
const U8 *end = in + inlen - left;\
|
||||||
\
|
\
|
||||||
U64 b = ( ( U64 )(inlen) ) << 56; \
|
U64 b = ( ( U64 )(inlen) ) << 56; \
|
||||||
U64 m; \
|
U64 m; \
|
||||||
U64 v0 = U8TO64_LE(state); \
|
U64 v0 = U8TO64_LE(state); \
|
||||||
U64 v1 = U8TO64_LE(state+8); \
|
U64 v1 = U8TO64_LE(state+8); \
|
||||||
U64 v2 = U8TO64_LE(state+16); \
|
U64 v2 = U8TO64_LE(state+16); \
|
||||||
U64 v3 = U8TO64_LE(state+24); \
|
U64 v3 = U8TO64_LE(state+24); \
|
||||||
\
|
\
|
||||||
for ( ; in != end; in += 8 ) \
|
for ( ; in != end; in += 8 ) \
|
||||||
{ \
|
{ \
|
||||||
m = U8TO64_LE( in ); \
|
m = U8TO64_LE( in ); \
|
||||||
v3 ^= m; \
|
v3 ^= m; \
|
||||||
\
|
\
|
||||||
SIP_ROUNDS; \
|
SIP_ROUNDS; \
|
||||||
\
|
\
|
||||||
v0 ^= m; \
|
v0 ^= m; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
switch( left ) \
|
switch( left ) \
|
||||||
{ \
|
{ \
|
||||||
case 7: b |= ( ( U64 )in[ 6] ) << 48; /*FALLTHROUGH*/ \
|
case 7: b |= ( ( U64 )in[ 6] ) << 48; /*FALLTHROUGH*/ \
|
||||||
case 6: b |= ( ( U64 )in[ 5] ) << 40; /*FALLTHROUGH*/ \
|
case 6: b |= ( ( U64 )in[ 5] ) << 40; /*FALLTHROUGH*/ \
|
||||||
case 5: b |= ( ( U64 )in[ 4] ) << 32; /*FALLTHROUGH*/ \
|
case 5: b |= ( ( U64 )in[ 4] ) << 32; /*FALLTHROUGH*/ \
|
||||||
@ -73,45 +73,52 @@ FNC ## _with_state_64 \
|
|||||||
case 3: b |= ( ( U64 )in[ 2] ) << 16; /*FALLTHROUGH*/ \
|
case 3: b |= ( ( U64 )in[ 2] ) << 16; /*FALLTHROUGH*/ \
|
||||||
case 2: b |= ( ( U64 )in[ 1] ) << 8; /*FALLTHROUGH*/ \
|
case 2: b |= ( ( U64 )in[ 1] ) << 8; /*FALLTHROUGH*/ \
|
||||||
case 1: b |= ( ( U64 )in[ 0] ); break; \
|
case 1: b |= ( ( U64 )in[ 0] ); break; \
|
||||||
case 0: break; \
|
case 0: break; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
v3 ^= b; \
|
v3 ^= b; \
|
||||||
\
|
\
|
||||||
SIP_ROUNDS; \
|
SIP_ROUNDS; \
|
||||||
\
|
\
|
||||||
v0 ^= b; \
|
v0 ^= b; \
|
||||||
\
|
\
|
||||||
v2 ^= 0xff; \
|
v2 ^= 0xff; \
|
||||||
\
|
\
|
||||||
SIP_FINAL_ROUNDS \
|
SIP_FINAL_ROUNDS \
|
||||||
\
|
\
|
||||||
b = v0 ^ v1 ^ v2 ^ v3; \
|
b = v0 ^ v1 ^ v2 ^ v3; \
|
||||||
return b; \
|
return b; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
PERL_STATIC_INLINE U32 \
|
PERL_STATIC_INLINE U32 \
|
||||||
FNC ## _with_state \
|
FNC ## _with_state \
|
||||||
(const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \
|
(const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \
|
||||||
{ \
|
{ \
|
||||||
union { \
|
union { \
|
||||||
U64 h64; \
|
U64 h64; \
|
||||||
U32 h32[2]; \
|
U32 h32[2]; \
|
||||||
} h; \
|
} h; \
|
||||||
h.h64= FNC ## _with_state_64(state,in,inlen); \
|
h.h64= FNC ## _with_state_64(state,in,inlen); \
|
||||||
return h.h32[0] ^ h.h32[1]; \
|
return h.h32[0] ^ h.h32[1]; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
PERL_STATIC_INLINE U32 \
|
PERL_STATIC_INLINE U32 \
|
||||||
FNC (const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) \
|
FNC (const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) \
|
||||||
{ \
|
{ \
|
||||||
U64 state[4]; \
|
U64 state[4]; \
|
||||||
SIPHASH_SEED_STATE(seed,state[0],state[1],state[2],state[3]); \
|
SIPHASH_SEED_STATE(seed,state[0],state[1],state[2],state[3]); \
|
||||||
return FNC ## _with_state((U8*)state,in,inlen); \
|
return FNC ## _with_state((U8*)state,in,inlen); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
PERL_STATIC_INLINE U64 \
|
||||||
|
FNC ## _64 (const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) \
|
||||||
|
{ \
|
||||||
|
U64 state[4]; \
|
||||||
|
SIPHASH_SEED_STATE(seed,state[0],state[1],state[2],state[3]); \
|
||||||
|
return FNC ## _with_state_64((U8*)state,in,inlen); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PERL_SIPHASH_FNC(
|
PERL_SIPHASH_FNC(
|
||||||
S_perl_hash_siphash_1_3
|
S_perl_hash_siphash_1_3
|
||||||
,SIPROUND;
|
,SIPROUND;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user