4 #ifndef SIP_HASH_STREAMING 5 #define SIP_HASH_STREAMING 1 9 #define BYTE_ORDER __LITTLE_ENDIAN 10 #elif !defined BYTE_ORDER 14 #define LITTLE_ENDIAN __LITTLE_ENDIAN 17 #define BIG_ENDIAN __BIG_ENDIAN 20 #if BYTE_ORDER == LITTLE_ENDIAN 23 #elif BYTE_ORDER == BIG_ENDIAN 27 #error "Only strictly little or big endian supported" 30 #ifndef UNALIGNED_WORD_ACCESS 31 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 32 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ 33 defined(__powerpc64__) || \ 35 # define UNALIGNED_WORD_ACCESS 1 38 #ifndef UNALIGNED_WORD_ACCESS 39 # define UNALIGNED_WORD_ACCESS 0 42 #define U8TO32_LE(p) \ 43 (((uint32_t)((p)[0]) ) | ((uint32_t)((p)[1]) << 8) | \ 44 ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) \ 46 #define U32TO8_LE(p, v) \ 48 (p)[0] = (uint8_t)((v) ); \ 49 (p)[1] = (uint8_t)((v) >> 8); \ 50 (p)[2] = (uint8_t)((v) >> 16); \ 51 (p)[3] = (uint8_t)((v) >> 24); \ 55 #define U8TO64_LE(p) \ 56 ((uint64_t)U8TO32_LE(p) | ((uint64_t)U8TO32_LE((p) + 4)) << 32 ) 58 #define U64TO8_LE(p, v) \ 60 U32TO8_LE((p), (uint32_t)((v) )); \ 61 U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); \ 64 #define ROTL64(v, s) \ 65 ((v) << (s)) | ((v) >> (64 - (s))) 67 #define ROTL64_TO(v, s) ((v) = ROTL64((v), (s))) 69 #define ADD64_TO(v, s) ((v) += (s)) 70 #define XOR64_TO(v, s) ((v) ^= (s)) 71 #define XOR64_INT(v, x) ((v) ^= (x)) 73 #define U8TO64_LE(p) u8to64_le(p) 83 #define U64TO8_LE(p, v) u64to8_le(p, v) 91 #define ROTL64_TO(v, s) ((s) > 32 ? rotl64_swap(rotl64_to(&(v), (s) - 32)) : \ 92 (s) == 32 ? rotl64_swap(&(v)) : rotl64_to(&(v), (s))) 94 rotl64_to(
uint64_t *v,
unsigned int s)
96 uint32_t uhi = (v->hi << s) | (v->lo >> (32 - s));
97 uint32_t ulo = (v->lo << s) | (v->hi >> (32 - s));
112 #define ADD64_TO(v, s) add64_to(&(v), (s)) 118 if (v->lo < s.lo) v->hi++;
122 #define XOR64_TO(v, s) xor64_to(&(v), (s)) 131 #define XOR64_INT(v, x) ((v).lo ^= (x)) 137 } sip_init_state_bin = {
"uespemos""modnarod""arenegyl""setybdet"};
138 #define sip_init_state sip_init_state_bin.u64 140 #if SIP_HASH_STREAMING 158 #define SIP_COMPRESS(v0, v1, v2, v3) \ 160 ADD64_TO((v0), (v1)); \ 161 ADD64_TO((v2), (v3)); \ 162 ROTL64_TO((v1), 13); \ 163 ROTL64_TO((v3), 16); \ 164 XOR64_TO((v1), (v0)); \ 165 XOR64_TO((v3), (v2)); \ 166 ROTL64_TO((v0), 32); \ 167 ADD64_TO((v2), (v1)); \ 168 ADD64_TO((v0), (v3)); \ 169 ROTL64_TO((v1), 17); \ 170 ROTL64_TO((v3), 21); \ 171 XOR64_TO((v1), (v2)); \ 172 XOR64_TO((v3), (v0)); \ 173 ROTL64_TO((v2), 32); \ 176 #if SIP_HASH_STREAMING 182 for (v = 0; v < 4; v++) {
184 printf(
"v%d: %" PRIx64
"\n", v, state->
v[v]);
186 printf(
"v%d: %" PRIx32
"%.8" PRIx32
"\n", v, state->
v[v].hi, state->
v[v].lo);
210 for (i = 0; i < n; i++) {
219 int_sip_round(state, state->
c);
229 if (!state->
buflen)
return;
232 memcpy(state->
buf + state->
buflen, *pdata, to_read);
234 int_sip_update_block(state, m);
245 memcpy(state->
buf, data + len - r, r);
259 int_sip_pre_update(state, &data, &len);
261 end = data64 + (len /
sizeof(
uint64_t));
263 #if BYTE_ORDER == LITTLE_ENDIAN 264 while (data64 != end) {
265 int_sip_update_block(state, *data64++);
267 #elif BYTE_ORDER == BIG_ENDIAN 273 int_sip_update_block(state, m);
278 int_sip_post_update(state, data, len);
282 int_sip_pad_final_block(
sip_state *state)
287 state->
buf[i] = 0x00;
297 int_sip_pad_final_block(state);
300 int_sip_update_block(state, m);
304 int_sip_round(state, state->
d);
306 *digest = state->
v[0];
385 int_sip_dump(h->
state);
389 #define SIP_ROUND(m, v0, v1, v2, v3) \ 391 XOR64_TO((v3), (m)); \ 392 SIP_COMPRESS(v0, v1, v2, v3); \ 393 XOR64_TO((v0), (m)); \ 412 #if BYTE_ORDER == LITTLE_ENDIAN && UNALIGNED_WORD_ACCESS 415 while (data64 != (
uint64_t *) end) {
421 for (; data != end; data +=
sizeof(
uint64_t)) {
429 #define OR_BYTE(n) (last |= ((uint64_t) end[n]) << ((n) * 8)) 433 #define OR_BYTE(n) do { \ 435 last.hi |= ((uint32_t) end[n]) << ((n) >= 4 ? (n) * 8 - 32 : 0); \ 437 last.lo |= ((uint32_t) end[n]) << ((n) >= 4 ? 0 : (n) * 8); \ 449 #if BYTE_ORDER == LITTLE_ENDIAN && UNALIGNED_WORD_ACCESS
const sip_interface * methods
int sip_hash_final_integer(sip_hash *h, uint64_t *digest)
uint8_t buf[sizeof(uint64_t)]
int sip_hash_update(sip_hash *h, const uint8_t *msg, size_t len)
void(* init)(sip_state *s, const uint8_t *key)
uint64_t sip_hash13(const uint8_t key[16], const uint8_t *data, size_t len)
int sip_hash_digest_integer(sip_hash *h, const uint8_t *data, size_t data_len, uint64_t *digest)
void sip_hash_free(sip_hash *h)
unsigned long long uint64_t
void(* update)(sip_state *s, const uint8_t *data, size_t len)
#define SIP_ROUND(m, v0, v1, v2, v3)
int sip_hash_final(sip_hash *h, uint8_t **digest, size_t *len)
sip_hash * sip_hash_new(const uint8_t key[16], int c, int d)
register unsigned int len
sip_hash * sip_hash_init(sip_hash *h, const uint8_t key[16], int c, int d)
void(* final)(sip_state *s, uint64_t *digest)
int sip_hash_digest(sip_hash *h, const uint8_t *data, size_t data_len, uint8_t **digest, size_t *digest_len)
void sip_hash_dump(sip_hash *h)
#define SIP_COMPRESS(v0, v1, v2, v3)