-
Notifications
You must be signed in to change notification settings - Fork 561
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix build for the two SipHash variations
fixes #16471
- Loading branch information
Showing
3 changed files
with
133 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* This is SipHash by Jean-Philippe Aumasson and Daniel J. Bernstein. | ||
* The authors claim it is relatively secure compared to the alternatives | ||
* and that performance wise it is a suitable hash for languages like Perl. | ||
* See: | ||
* | ||
* https://www.131002.net/siphash/ | ||
* | ||
* This implementation seems to perform slightly slower than one-at-a-time for | ||
* short keys, but degrades slower for longer keys. Murmur Hash outperforms it | ||
* regardless of keys size. | ||
* | ||
* It is 64 bit only. | ||
*/ | ||
|
||
#ifdef CAN64BITHASH | ||
|
||
#define SIPROUND \ | ||
STMT_START { \ | ||
v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \ | ||
v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \ | ||
v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \ | ||
v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \ | ||
} STMT_END | ||
|
||
#define SIPHASH_SEED_STATE(key,v0,v1,v2,v3) \ | ||
do { \ | ||
v0 = v2 = U8TO64_LE(key + 0); \ | ||
v1 = v3 = U8TO64_LE(key + 8); \ | ||
/* "somepseudorandomlygeneratedbytes" */ \ | ||
v0 ^= UINT64_C(0x736f6d6570736575); \ | ||
v1 ^= UINT64_C(0x646f72616e646f6d); \ | ||
v2 ^= UINT64_C(0x6c7967656e657261); \ | ||
v3 ^= UINT64_C(0x7465646279746573); \ | ||
} while (0) | ||
|
||
PERL_STATIC_INLINE | ||
void S_perl_siphash_seed_state(const unsigned char * const seed_buf, unsigned char * state_buf) { | ||
U64 *v= (U64*) state_buf; | ||
SIPHASH_SEED_STATE(seed_buf, v[0],v[1],v[2],v[3]); | ||
} | ||
|
||
#define PERL_SIPHASH_FNC(FNC,SIP_ROUNDS,SIP_FINAL_ROUNDS) \ | ||
PERL_STATIC_INLINE U64 \ | ||
FNC ## _with_state_64 \ | ||
(const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \ | ||
{ \ | ||
const int left = inlen & 7; \ | ||
const U8 *end = in + inlen - left; \ | ||
\ | ||
U64 b = ( ( U64 )(inlen) ) << 56; \ | ||
U64 m; \ | ||
U64 v0 = U8TO64_LE(state); \ | ||
U64 v1 = U8TO64_LE(state+8); \ | ||
U64 v2 = U8TO64_LE(state+16); \ | ||
U64 v3 = U8TO64_LE(state+24); \ | ||
\ | ||
for ( ; in != end; in += 8 ) \ | ||
{ \ | ||
m = U8TO64_LE( in ); \ | ||
v3 ^= m; \ | ||
\ | ||
SIP_ROUNDS; \ | ||
\ | ||
v0 ^= m; \ | ||
} \ | ||
\ | ||
switch( left ) \ | ||
{ \ | ||
case 7: b |= ( ( U64 )in[ 6] ) << 48; /*FALLTHROUGH*/ \ | ||
case 6: b |= ( ( U64 )in[ 5] ) << 40; /*FALLTHROUGH*/ \ | ||
case 5: b |= ( ( U64 )in[ 4] ) << 32; /*FALLTHROUGH*/ \ | ||
case 4: b |= ( ( U64 )in[ 3] ) << 24; /*FALLTHROUGH*/ \ | ||
case 3: b |= ( ( U64 )in[ 2] ) << 16; /*FALLTHROUGH*/ \ | ||
case 2: b |= ( ( U64 )in[ 1] ) << 8; /*FALLTHROUGH*/ \ | ||
case 1: b |= ( ( U64 )in[ 0] ); break; \ | ||
case 0: break; \ | ||
} \ | ||
\ | ||
v3 ^= b; \ | ||
\ | ||
SIP_ROUNDS; \ | ||
\ | ||
v0 ^= b; \ | ||
\ | ||
v2 ^= 0xff; \ | ||
\ | ||
SIP_FINAL_ROUNDS \ | ||
\ | ||
b = v0 ^ v1 ^ v2 ^ v3; \ | ||
return b; \ | ||
} \ | ||
\ | ||
PERL_STATIC_INLINE U32 \ | ||
FNC ## _with_state \ | ||
(const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \ | ||
{ \ | ||
union { \ | ||
U64 h64; \ | ||
U32 h32[2]; \ | ||
} h; \ | ||
h.h64= FNC ## _with_state_64(state,in,inlen); \ | ||
return h.h32[0] ^ h.h32[1]; \ | ||
} \ | ||
\ | ||
\ | ||
PERL_STATIC_INLINE U32 \ | ||
FNC (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((U8*)state,in,inlen); \ | ||
} | ||
|
||
|
||
PERL_SIPHASH_FNC( | ||
S_perl_hash_siphash_1_3 | ||
,SIPROUND; | ||
,SIPROUND;SIPROUND;SIPROUND; | ||
) | ||
|
||
PERL_SIPHASH_FNC( | ||
S_perl_hash_siphash_2_4 | ||
,SIPROUND;SIPROUND; | ||
,SIPROUND;SIPROUND;SIPROUND;SIPROUND; | ||
) | ||
|
||
#endif /* defined(CAN64BITHASH) */ |