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__) || defined(__aarch64__) || \
35# define UNALIGNED_WORD_ACCESS 1
38#ifndef UNALIGNED_WORD_ACCESS
39# define UNALIGNED_WORD_ACCESS 0
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); \
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)); \
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)))
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
141struct sip_interface_st {
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++) {
210 for (
i = 0;
i <
n;
i++) {
219 int_sip_round(state, state->
c);
229 if (!state->
buflen)
return;
234 int_sip_update_block(state, m);
259 int_sip_pre_update(state, &data, &
len);
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);
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];
326 h->state->buflen = 0;
327 h->state->msglen_byte = 0;
328 h->methods = &sip_methods;
329 h->methods->init(
h->state,
key);
336 h->methods->update(
h->state, msg,
len);
346 h->methods->final(
h->state, &digest64);
358 h->methods->final(
h->state, digest);
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
#define SIP_COMPRESS(v0, v1, v2, v3)
uint64_t sip_hash13(const uint8_t key[16], const uint8_t *data, size_t len)
#define SIP_ROUND(m, v0, v1, v2, v3)
int sip_hash_digest(sip_hash *h, const uint8_t *data, size_t data_len, uint8_t **digest, size_t *digest_len)
sip_hash * sip_hash_init(sip_hash *h, const uint8_t key[16], int c, int d)
void sip_hash_free(sip_hash *h)
int sip_hash_final_integer(sip_hash *h, uint64_t *digest)
int sip_hash_update(sip_hash *h, const uint8_t *data, size_t len)
int sip_hash_final(sip_hash *h, uint8_t **digest, size_t *len)
int sip_hash_digest_integer(sip_hash *h, const uint8_t *data, size_t data_len, uint64_t *digest)
struct sip_interface_st sip_interface
sip_hash * sip_hash_new(const uint8_t key[16], int c, int d)
void sip_hash_dump(sip_hash *h)
uint8_t buf[sizeof(uint64_t)]