1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-08 05:57:26 +03:00

Merge pull request #1474 from teg/siphash24

siphash: style fixes
This commit is contained in:
Daniel Mack 2015-10-06 18:12:25 +02:00
commit ac773fd8d5
7 changed files with 149 additions and 154 deletions

View File

@ -372,12 +372,15 @@ static uint8_t *hash_key(HashmapBase *h) {
static unsigned base_bucket_hash(HashmapBase *h, const void *p) { static unsigned base_bucket_hash(HashmapBase *h, const void *p) {
struct siphash state; struct siphash state;
uint64_t hash;
siphash_init(&state, hash_key(h)); siphash24_init(&state, hash_key(h));
h->hash_ops->hash(p, &state); h->hash_ops->hash(p, &state);
return (unsigned) (siphash24_finalize(&state) % n_buckets(h)); siphash24_finalize((uint8_t*)&hash, &state);
return (unsigned) (hash % n_buckets(h));
} }
#define bucket_hash(h, p) base_bucket_hash(HASHMAP_BASE(h), p) #define bucket_hash(h, p) base_bucket_hash(HASHMAP_BASE(h), p)

View File

@ -13,175 +13,170 @@
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
(Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd) (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd)
(Refactored by Tom Gundersen to split up in several functions and follow systemd
coding style)
*/ */
#include <stdint.h>
#include <stdio.h> #include "sparse-endian.h"
#include <string.h>
#include "siphash24.h" #include "siphash24.h"
#include "util.h"
typedef uint64_t u64; static inline uint64_t rotate_left(uint64_t x, uint8_t b) {
typedef uint32_t u32; assert(b < 64);
typedef uint8_t u8;
#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) ) return (x << b) | (x >> (64 - b));
}
#define U32TO8_LE(p, v) \ static inline void sipround(struct siphash *state) {
(p)[0] = (u8)((v) ); (p)[1] = (u8)((v) >> 8); \ assert(state);
(p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
#define U64TO8_LE(p, v) \ state->v0 += state->v1;
U32TO8_LE((p), (u32)((v) )); \ state->v1 = rotate_left(state->v1, 13);
U32TO8_LE((p) + 4, (u32)((v) >> 32)); state->v1 ^= state->v0;
state->v0 = rotate_left(state->v0, 32);
state->v2 += state->v3;
state->v3 = rotate_left(state->v3, 16);
state->v3 ^= state->v2;
state->v0 += state->v3;
state->v3 = rotate_left(state->v3, 21);
state->v3 ^= state->v0;
state->v2 += state->v1;
state->v1 = rotate_left(state->v1, 17);
state->v1 ^= state->v2;
state->v2 = rotate_left(state->v2, 32);
}
#define U8TO64_LE(p) \ void siphash24_init(struct siphash *state, const uint8_t k[16]) {
(((u64)((p)[0]) ) | \ uint64_t k0, k1;
((u64)((p)[1]) << 8) | \
((u64)((p)[2]) << 16) | \
((u64)((p)[3]) << 24) | \
((u64)((p)[4]) << 32) | \
((u64)((p)[5]) << 40) | \
((u64)((p)[6]) << 48) | \
((u64)((p)[7]) << 56))
#define SIPROUND(state) \ assert(state);
do { \ assert(k);
(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)
void siphash_init(struct siphash *state, const uint8_t k[16]) { k0 = le64toh(*(le64_t*) k);
u64 k0, k1; k1 = le64toh(*(le64_t*) (k + 8));
k0 = U8TO64_LE( k ); /* "somepseudorandomlygeneratedbytes" */
k1 = U8TO64_LE( k + 8 ); state->v0 = 0x736f6d6570736575ULL ^ k0;
state->v1 = 0x646f72616e646f6dULL ^ k1;
/* "somepseudorandomlygeneratedbytes" */ state->v2 = 0x6c7967656e657261ULL ^ k0;
state->v0 = 0x736f6d6570736575ULL ^ k0; state->v3 = 0x7465646279746573ULL ^ k1;
state->v1 = 0x646f72616e646f6dULL ^ k1; state->padding = 0;
state->v2 = 0x6c7967656e657261ULL ^ k0; state->inlen = 0;
state->v3 = 0x7465646279746573ULL ^ k1;
state->padding = 0;
state->inlen = 0;
} }
void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
u64 m; uint64_t m;
const u8 *in = _in; const uint8_t *in = _in;
const u8 *end = in + inlen; const uint8_t *end = in + inlen;
int left = state->inlen & 7; unsigned left = state->inlen & 7;
/* update total length */ assert(in);
state->inlen += inlen; assert(state);
/* if padding exists, fill it out */ /* update total length */
if (left > 0) { state->inlen += inlen;
for ( ; in < end && left < 8; in ++, left ++ )
state->padding |= ( ( u64 )*in ) << (left * 8);
if (in == end && left < 8) /* if padding exists, fill it out */
/* we did not have enough input to fill out the padding completely */ if (left > 0) {
return; for ( ; in < end && left < 8; in ++, left ++ )
state->padding |= ( ( uint64_t )*in ) << (left * 8);
if (in == end && left < 8)
/* we did not have enough input to fill out the padding completely */
return;
#ifdef DEBUG #ifdef DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
printf( "(%3d) compress padding %08x %08x\n", ( int )state->inlen, ( u32 )( state->padding >> 32 ), ( u32 )state->padding ); printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding);
#endif #endif
state->v3 ^= state->padding; state->v3 ^= state->padding;
SIPROUND(state); sipround(state);
SIPROUND(state); sipround(state);
state->v0 ^= state->padding; state->v0 ^= state->padding;
state->padding = 0; state->padding = 0;
} }
end -= ( state->inlen % sizeof (u64) ); end -= ( state->inlen % sizeof (uint64_t) );
for ( ; in < end; in += 8 ) for ( ; in < end; in += 8 ) {
{ m = le64toh(*(le64_t*) in);
m = U8TO64_LE( in );
#ifdef DEBUG #ifdef DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
printf( "(%3d) compress %08x %08x\n", ( int )state->inlen, ( u32 )( m >> 32 ), ( u32 )m ); printf("(%3zu) compress %08x %08x\n", state->inlen, (uint32_t) (m >> 32), (uint32_t) m);
#endif #endif
state->v3 ^= m; state->v3 ^= m;
SIPROUND(state); sipround(state);
SIPROUND(state); sipround(state);
state->v0 ^= m; state->v0 ^= m;
} }
left = state->inlen & 7; left = state->inlen & 7;
switch( left ) switch(left)
{ {
case 7: state->padding |= ( ( u64 )in[ 6] ) << 48; case 7: state->padding |= ((uint64_t) in[6]) << 48;
case 6: state->padding |= ( ( u64 )in[ 5] ) << 40; case 6: state->padding |= ((uint64_t) in[5]) << 40;
case 5: state->padding |= ( ( u64 )in[ 4] ) << 32; case 5: state->padding |= ((uint64_t) in[4]) << 32;
case 4: state->padding |= ( ( u64 )in[ 3] ) << 24; case 4: state->padding |= ((uint64_t) in[3]) << 24;
case 3: state->padding |= ( ( u64 )in[ 2] ) << 16; case 3: state->padding |= ((uint64_t) in[2]) << 16;
case 2: state->padding |= ( ( u64 )in[ 1] ) << 8; case 2: state->padding |= ((uint64_t) in[1]) << 8;
case 1: state->padding |= ( ( u64 )in[ 0] ); break; case 1: state->padding |= ((uint64_t) in[0]); break;
case 0: break; case 0: break;
} }
} }
uint64_t siphash24_finalize(struct siphash *state) { void siphash24_finalize(uint8_t out[8], struct siphash *state) {
u64 b; uint64_t b;
b = state->padding | (( ( u64 )state->inlen ) << 56); b = state->padding | (( ( uint64_t )state->inlen ) << 56);
#ifdef DEBUG #ifdef DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t)state->v0);
printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t)state->v1);
printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t)state->v2);
printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t)state->v3);
printf( "(%3d) padding %08x %08x\n", ( int )state->inlen, ( u32 )( state->padding >> 32 ), ( u32 )state->padding ); printf("(%3zu) padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding);
#endif #endif
state->v3 ^= b; state->v3 ^= b;
SIPROUND(state); sipround(state);
SIPROUND(state); sipround(state);
state->v0 ^= b; state->v0 ^= b;
#ifdef DEBUG #ifdef DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v0 >> 32 ), ( u32 )state->v0 ); printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
printf( "(%3d) v1 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v1 >> 32 ), ( u32 )state->v1 ); printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
printf( "(%3d) v2 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v2 >> 32 ), ( u32 )state->v2 ); printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
printf( "(%3d) v3 %08x %08x\n", ( int )state->inlen, ( u32 )( state->v3 >> 32 ), ( u32 )state->v3 ); printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
#endif #endif
state->v2 ^= 0xff; state->v2 ^= 0xff;
SIPROUND(state);
SIPROUND(state);
SIPROUND(state);
SIPROUND(state);
return state->v0 ^ state->v1 ^ state->v2 ^ state->v3; sipround(state);
sipround(state);
sipround(state);
sipround(state);
*(le64_t*)out = htole64(state->v0 ^ state->v1 ^ state->v2 ^ state->v3);
} }
/* SipHash-2-4 */ /* SipHash-2-4 */
void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) {
{ struct siphash state;
struct siphash state;
u64 b;
siphash_init(&state, k); siphash24_init(&state, k);
siphash24_compress(_in, inlen, &state);
siphash24_compress(_in, inlen, &state); siphash24_finalize(out, &state);
b = siphash24_finalize(&state);
U64TO8_LE( out, b );
} }

View File

@ -12,8 +12,8 @@ struct siphash {
size_t inlen; size_t inlen;
}; };
void siphash_init(struct siphash *state, const uint8_t k[16]); void siphash24_init(struct siphash *state, const uint8_t k[16]);
void siphash24_compress(const void *in, size_t inlen, struct siphash *state); void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
uint64_t siphash24_finalize(struct siphash *state); void siphash24_finalize(uint8_t out[8], struct siphash *state);
void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]); void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]);

View File

@ -57,7 +57,7 @@ struct JournalRateLimitGroup {
char *id; char *id;
JournalRateLimitPool pools[POOLS_MAX]; JournalRateLimitPool pools[POOLS_MAX];
unsigned long hash; uint64_t hash;
LIST_FIELDS(JournalRateLimitGroup, bucket); LIST_FIELDS(JournalRateLimitGroup, bucket);
LIST_FIELDS(JournalRateLimitGroup, lru); LIST_FIELDS(JournalRateLimitGroup, lru);
@ -158,9 +158,9 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
if (!g->id) if (!g->id)
goto fail; goto fail;
siphash_init(&state, r->hash_key); siphash24_init(&state, r->hash_key);
string_hash_func(g->id, &state); string_hash_func(g->id, &state);
g->hash = siphash24_finalize(&state); siphash24_finalize((uint8_t*)&g->hash, &state);
journal_rate_limit_vacuum(r, ts); journal_rate_limit_vacuum(r, ts);
@ -207,7 +207,7 @@ static unsigned burst_modulate(unsigned burst, uint64_t available) {
} }
int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) { int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
unsigned long h; uint64_t h;
JournalRateLimitGroup *g; JournalRateLimitGroup *g;
JournalRateLimitPool *p; JournalRateLimitPool *p;
struct siphash state; struct siphash state;
@ -226,9 +226,9 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
ts = now(CLOCK_MONOTONIC); ts = now(CLOCK_MONOTONIC);
siphash_init(&state, r->hash_key); siphash24_init(&state, r->hash_key);
string_hash_func(id, &state); string_hash_func(id, &state);
h = siphash24_finalize(&state); siphash24_finalize((uint8_t*)&h, &state);
g = r->buckets[h % BUCKETS_MAX]; g = r->buckets[h % BUCKETS_MAX];
LIST_FOREACH(bucket, g, g) LIST_FOREACH(bucket, g, g)

View File

@ -741,15 +741,17 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
address = existing_lease->address; address = existing_lease->address;
else { else {
struct siphash state; struct siphash state;
uint64_t hash;
uint32_t next_offer; uint32_t next_offer;
/* even with no persistence of leases, we try to offer the same client /* even with no persistence of leases, we try to offer the same client
the same IP address. we do this by using the hash of the client id the same IP address. we do this by using the hash of the client id
as the offset into the pool of leases when finding the next free one */ as the offset into the pool of leases when finding the next free one */
siphash_init(&state, HASH_KEY.bytes); siphash24_init(&state, HASH_KEY.bytes);
client_id_hash_func(&req->client_id, &state); client_id_hash_func(&req->client_id, &state);
next_offer = siphash24_finalize(&state) % server->pool_size; siphash24_finalize((uint8_t*)&hash, &state);
next_offer = hash % server->pool_size;
for (i = 0; i < server->pool_size; i++) { for (i = 0; i < server->pool_size; i++) {
if (!server->bound_leases[next_offer]) { if (!server->bound_leases[next_offer]) {

View File

@ -200,10 +200,13 @@ static void test_message_handler(void) {
static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZE]) { static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZE]) {
struct siphash state; struct siphash state;
uint64_t hash;
siphash_init(&state, key); siphash24_init(&state, key);
client_id_hash_func(id, &state); client_id_hash_func(id, &state);
return siphash24_finalize(&state); siphash24_finalize((uint8_t*)&hash, &state);
return hash;
} }
static void test_client_id_hash(void) { static void test_client_id_hash(void) {

View File

@ -32,23 +32,13 @@ int main(int argc, char *argv[]) {
const uint8_t key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, const uint8_t key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
uint64_t out = 0; uint64_t out = 0;
unsigned i, j, k; unsigned i, j;
usec_t ts;
siphash24((uint8_t *)&out, in, sizeof(in), key); siphash24((uint8_t *)&out, in, sizeof(in), key);
assert_se(out == 0xa129ca6149be45e5); assert_se(out == htole64(0xa129ca6149be45e5));
assert_se(out == 0xa129ca6149be45e5ULL);
ts = now(CLOCK_MONOTONIC);
for (k = 0; k < ITERATIONS; k++)
siphash24((uint8_t *)&out, in, sizeof(in), key);
ts = now(CLOCK_MONOTONIC) - ts;
log_info("%llu iterations per second", (ITERATIONS * USEC_PER_SEC) / ts);
/* verify the internal state as given in the above paper */ /* verify the internal state as given in the above paper */
siphash_init(&state, key); siphash24_init(&state, key);
assert_se(state.v0 == 0x7469686173716475); assert_se(state.v0 == 0x7469686173716475);
assert_se(state.v1 == 0x6b617f6d656e6665); assert_se(state.v1 == 0x6b617f6d656e6665);
assert_se(state.v2 == 0x6b7f62616d677361); assert_se(state.v2 == 0x6b7f62616d677361);
@ -58,7 +48,8 @@ int main(int argc, char *argv[]) {
assert_se(state.v1 == 0x0d52f6f62a4f59a4); assert_se(state.v1 == 0x0d52f6f62a4f59a4);
assert_se(state.v2 == 0x634cb3577b01fd3d); assert_se(state.v2 == 0x634cb3577b01fd3d);
assert_se(state.v3 == 0xa5224d6f55c7d9c8); assert_se(state.v3 == 0xa5224d6f55c7d9c8);
assert_se(siphash24_finalize(&state) == 0xa129ca6149be45e5); siphash24_finalize((uint8_t*)&out, &state);
assert_se(out == htole64(0xa129ca6149be45e5));
assert_se(state.v0 == 0xf6bcd53893fecff1); assert_se(state.v0 == 0xf6bcd53893fecff1);
assert_se(state.v1 == 0x54b9964c7ea0d937); assert_se(state.v1 == 0x54b9964c7ea0d937);
assert_se(state.v2 == 0x1b38329c099bb55a); assert_se(state.v2 == 0x1b38329c099bb55a);
@ -68,11 +59,12 @@ int main(int argc, char *argv[]) {
same result */ same result */
for (i = 0; i < sizeof(in); i++) { for (i = 0; i < sizeof(in); i++) {
for (j = i; j < sizeof(in); j++) { for (j = i; j < sizeof(in); j++) {
siphash_init(&state, key); siphash24_init(&state, key);
siphash24_compress(in, i, &state); siphash24_compress(in, i, &state);
siphash24_compress(&in[i], j - i, &state); siphash24_compress(&in[i], j - i, &state);
siphash24_compress(&in[j], sizeof(in) - j, &state); siphash24_compress(&in[j], sizeof(in) - j, &state);
assert_se(siphash24_finalize(&state) == 0xa129ca6149be45e5); siphash24_finalize((uint8_t*)&out, &state);
assert_se(out == htole64(0xa129ca6149be45e5));
} }
} }
} }