File Coverage

mph_siphash.h
Criterion Covered Total %
statement 5 5 100.0
branch 2 2 100.0
condition n/a
subroutine n/a
pod n/a
total 7 7 100.0


line stmt bran cond sub pod time code
1             #ifndef _MPH_HASH_H
2             #define _MPH_HASH_H
3              
4             #ifndef SIPROUND
5             #define SIPROUND \
6             STMT_START { \
7             v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
8             v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
9             v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
10             v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
11             } STMT_END
12             #endif
13              
14             #ifndef SIPHASH_SEED_STATE
15             #define SIPHASH_SEED_STATE(key,v0,v1,v2,v3) \
16             do { \
17             v0 = v2 = U8TO64_LE(key + 0); \
18             v1 = v3 = U8TO64_LE(key + 8); \
19             /* "somepseudorandomlygeneratedbytes" */ \
20             v0 ^= UINT64_C(0x736f6d6570736575); \
21             v1 ^= UINT64_C(0x646f72616e646f6d); \
22             v2 ^= UINT64_C(0x6c7967656e657261); \
23             v3 ^= UINT64_C(0x7465646279746573); \
24             } while (0)
25             #endif
26              
27             #define MPH_SIPHASH_FNC(FNC,SIP_ROUNDS,SIP_FINAL_ROUNDS) \
28             MPH_STATIC_INLINE U64 \
29             FNC ## _with_state \
30             (const unsigned char * const state, const unsigned char *in, const STRLEN inlen) \
31             { \
32             const int left = inlen & 7; \
33             const U8 *end = in + inlen - left; \
34             \
35             U64 b = ( ( U64 )(inlen) ) << 56; \
36             U64 m; \
37             U64 v0 = U8TO64_LE(state); \
38             U64 v1 = U8TO64_LE(state+8); \
39             U64 v2 = U8TO64_LE(state+16); \
40             U64 v3 = U8TO64_LE(state+24); \
41             \
42             for ( ; in != end; in += 8 ) \
43             { \
44             m = U8TO64_LE( in ); \
45             v3 ^= m; \
46             \
47             SIP_ROUNDS; \
48             \
49             v0 ^= m; \
50             } \
51             \
52             switch( left ) \
53             { \
54             case 7: b |= ( ( U64 )in[ 6] ) << 48; \
55             case 6: b |= ( ( U64 )in[ 5] ) << 40; \
56             case 5: b |= ( ( U64 )in[ 4] ) << 32; \
57             case 4: b |= ( ( U64 )in[ 3] ) << 24; \
58             case 3: b |= ( ( U64 )in[ 2] ) << 16; \
59             case 2: b |= ( ( U64 )in[ 1] ) << 8; \
60             case 1: b |= ( ( U64 )in[ 0] ); break; \
61             case 0: break; \
62             } \
63             \
64             v3 ^= b; \
65             \
66             SIP_ROUNDS; \
67             \
68             v0 ^= b; \
69             \
70             v2 ^= 0xff; \
71             \
72             SIP_FINAL_ROUNDS \
73             \
74             b = v0 ^ v1 ^ v2 ^ v3; \
75             return b; \
76             } \
77             \
78             MPH_STATIC_INLINE U64 \
79             FNC (const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) \
80             { \
81             U64 state[4]; \
82             SIPHASH_SEED_STATE(seed,state[0],state[1],state[2],state[3]); \
83             return FNC ## _with_state((U8*)state,in,inlen); \
84             }
85              
86              
87             MPH_STATIC_INLINE
88 96           void mph_seed_state(const unsigned char * const seed_buf, unsigned char * state_buf) {
89 96           U64 *v= (U64*) state_buf;
90 96           SIPHASH_SEED_STATE(seed_buf, v[0],v[1],v[2],v[3]);
91 96           }
92              
93              
94 4590876 100         MPH_SIPHASH_FNC(
95             mph_hash
96             ,SIPROUND;
97             ,SIPROUND;SIPROUND;SIPROUND;
98             )
99              
100             #endif
101