diff options
Diffstat (limited to 'src/basic/siphash24.c')
-rw-r--r-- | src/basic/siphash24.c | 170 |
1 files changed, 111 insertions, 59 deletions
diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c index f68bd283a1..308e4230c5 100644 --- a/src/basic/siphash24.c +++ b/src/basic/siphash24.c @@ -44,92 +44,144 @@ typedef uint8_t u8; ((u64)((p)[6]) << 48) | \ ((u64)((p)[7]) << 56)) -#define SIPROUND \ +#define SIPROUND(state) \ do { \ - v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \ - v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \ - v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \ - v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \ + (state)->v0 += (state)->v1; (state)->v1=ROTL((state)->v1,13); (state)->v1 ^= (state)->v0; (state)->v0=ROTL((state)->v0,32); \ + (state)->v2 += (state)->v3; (state)->v3=ROTL((state)->v3,16); (state)->v3 ^= (state)->v2; \ + (state)->v0 += (state)->v3; (state)->v3=ROTL((state)->v3,21); (state)->v3 ^= (state)->v0; \ + (state)->v2 += (state)->v1; (state)->v1=ROTL((state)->v1,17); (state)->v1 ^= (state)->v2; (state)->v2=ROTL((state)->v2,32); \ } while(0) -/* SipHash-2-4 */ -void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) -{ +void siphash_init(struct siphash *state, const uint8_t k[16]) { + u64 k0, k1; + + k0 = U8TO64_LE( k ); + k1 = U8TO64_LE( k + 8 ); + /* "somepseudorandomlygeneratedbytes" */ - u64 v0 = 0x736f6d6570736575ULL; - u64 v1 = 0x646f72616e646f6dULL; - u64 v2 = 0x6c7967656e657261ULL; - u64 v3 = 0x7465646279746573ULL; - u64 b; - u64 k0 = U8TO64_LE( k ); - u64 k1 = U8TO64_LE( k + 8 ); + state->v0 = 0x736f6d6570736575ULL ^ k0; + state->v1 = 0x646f72616e646f6dULL ^ k1; + state->v2 = 0x6c7967656e657261ULL ^ k0; + state->v3 = 0x7465646279746573ULL ^ k1; + state->padding = 0; + state->inlen = 0; +} + +void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { u64 m; const u8 *in = _in; - const u8 *end = in + inlen - ( inlen % sizeof( u64 ) ); - const int left = inlen & 7; - b = ( ( u64 )inlen ) << 56; - v3 ^= k1; - v2 ^= k0; - v1 ^= k1; - v0 ^= k0; - - for ( ; in != end; in += 8 ) + const u8 *end = in + inlen; + int left = state->inlen & 7; + + /* update total length */ + state->inlen += inlen; + + /* if padding exists, fill it out */ + if (left > 0) { + for ( ; in < end && left < 8; in ++, left ++ ) + state->padding |= ( ( u64 )*in ) << (left * 8); + + if (in == end && left < 8) + /* we did not have enough input to fill out the padding completely */ + return; + +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); + printf( "(%3d) compress padding %08x %08x\n", ( int )state->inlen, ( u32 )( state->padding >> 32 ), ( u32 )state->padding ); +#endif + state->v3 ^= state->padding; + SIPROUND(state); + SIPROUND(state); + state->v0 ^= state->padding; + + state->padding = 0; + } + + end -= ( state->inlen % sizeof (u64) ); + + for ( ; in < end; in += 8 ) { m = U8TO64_LE( in ); #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); - printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m ); + printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); + printf( "(%3d) compress %08x %08x\n", ( int )state->inlen, ( u32 )( m >> 32 ), ( u32 )m ); #endif - v3 ^= m; - SIPROUND; - SIPROUND; - v0 ^= m; + state->v3 ^= m; + SIPROUND(state); + SIPROUND(state); + state->v0 ^= m; } + left = state->inlen & 7; + switch( left ) { - case 7: b |= ( ( u64 )in[ 6] ) << 48; + case 7: state->padding |= ( ( u64 )in[ 6] ) << 48; - case 6: b |= ( ( u64 )in[ 5] ) << 40; + case 6: state->padding |= ( ( u64 )in[ 5] ) << 40; - case 5: b |= ( ( u64 )in[ 4] ) << 32; + case 5: state->padding |= ( ( u64 )in[ 4] ) << 32; - case 4: b |= ( ( u64 )in[ 3] ) << 24; + case 4: state->padding |= ( ( u64 )in[ 3] ) << 24; - case 3: b |= ( ( u64 )in[ 2] ) << 16; + case 3: state->padding |= ( ( u64 )in[ 2] ) << 16; - case 2: b |= ( ( u64 )in[ 1] ) << 8; + case 2: state->padding |= ( ( u64 )in[ 1] ) << 8; - case 1: b |= ( ( u64 )in[ 0] ); break; + case 1: state->padding |= ( ( u64 )in[ 0] ); break; case 0: break; } +} + +uint64_t siphash24_finalize(struct siphash *state) { + u64 b; + b = state->padding | (( ( u64 )state->inlen ) << 56); #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); - printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b ); + printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); + printf( "(%3d) padding %08x %08x\n", ( int )state->inlen, ( u32 )( state->padding >> 32 ), ( u32 )state->padding ); #endif - v3 ^= b; - SIPROUND; - SIPROUND; - v0 ^= b; + state->v3 ^= b; + SIPROUND(state); + SIPROUND(state); + state->v0 ^= b; + #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); #endif - v2 ^= 0xff; - SIPROUND; - SIPROUND; - SIPROUND; - SIPROUND; - b = v0 ^ v1 ^ v2 ^ v3; + state->v2 ^= 0xff; + SIPROUND(state); + SIPROUND(state); + SIPROUND(state); + SIPROUND(state); + + return state->v0 ^ state->v1 ^ state->v2 ^ state->v3; +} + +/* SipHash-2-4 */ +void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) +{ + struct siphash state; + u64 b; + + siphash_init(&state, k); + + siphash24_compress(_in, inlen, &state); + + b = siphash24_finalize(&state); + U64TO8_LE( out, b ); } |