X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fbasic%2Fsiphash24.c;h=8f2f1f55348d654958ec12f7c28e18120498fe74;hp=e7adfe48c83b4cac5bb0b8abb128c7382e2b13b5;hb=16a5cb267fa73a03afc91c372ccc2326db61aa71;hpb=f0928320e79e1cce13d6a21cfdd602cf4a12ccf4 diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c index e7adfe48c..8f2f1f553 100644 --- a/src/basic/siphash24.c +++ b/src/basic/siphash24.c @@ -57,6 +57,8 @@ struct siphash { u64 v1; u64 v2; u64 v3; + u64 padding; + size_t inlen; }; static void siphash_init(struct siphash *state, const uint8_t k[16]) { @@ -70,83 +72,94 @@ static void siphash_init(struct siphash *state, const uint8_t k[16]) { state->v1 = 0x646f72616e646f6dULL ^ k1; state->v2 = 0x6c7967656e657261ULL ^ k0; state->v3 = 0x7465646279746573ULL ^ k1; + state->padding = 0; + state->inlen = 0; } -static u64 siphash24_finalize(struct siphash *state) { - 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; +static 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; - siphash_init(&state, k); + state->inlen = inlen; for ( ; in != end; in += 8 ) { m = U8TO64_LE( in ); #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( state.v0 >> 32 ), ( u32 )state.v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( state.v1 >> 32 ), ( u32 )state.v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( state.v2 >> 32 ), ( u32 )state.v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( state.v3 >> 32 ), ( u32 )state.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 - state.v3 ^= m; - SIPROUND(&state); - SIPROUND(&state); - state.v0 ^= m; + state->v3 ^= m; + SIPROUND(state); + SIPROUND(state); + state->v0 ^= m; } 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; } +} + +static u64 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 )( state.v0 >> 32 ), ( u32 )state.v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( state.v1 >> 32 ), ( u32 )state.v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( state.v2 >> 32 ), ( u32 )state.v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( state.v3 >> 32 ), ( u32 )state.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 - state.v3 ^= b; - SIPROUND(&state); - SIPROUND(&state); - state.v0 ^= b; + state->v3 ^= b; + SIPROUND(state); + SIPROUND(state); + state->v0 ^= b; + #ifdef DEBUG - printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( state.v0 >> 32 ), ( u32 )state.v0 ); - printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( state.v1 >> 32 ), ( u32 )state.v1 ); - printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( state.v2 >> 32 ), ( u32 )state.v2 ); - printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( state.v3 >> 32 ), ( u32 )state.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 + 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);