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_AMD86) || \
34 # define UNALIGNED_WORD_ACCESS 1
37 #ifndef UNALIGNED_WORD_ACCESS
38 # define UNALIGNED_WORD_ACCESS 0
41 #define U8TO32_LE(p) \
42 (((uint32_t)((p)[0]) ) | ((uint32_t)((p)[1]) << 8) | \
43 ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) \
45 #define U32TO8_LE(p, v) \
47 (p)[0] = (uint8_t)((v) ); \
48 (p)[1] = (uint8_t)((v) >> 8); \
49 (p)[2] = (uint8_t)((v) >> 16); \
50 (p)[3] = (uint8_t)((v) >> 24); \
54 #define U8TO64_LE(p) \
55 ((uint64_t)U8TO32_LE(p) | ((uint64_t)U8TO32_LE((p) + 4)) << 32 )
57 #define U64TO8_LE(p, v) \
59 U32TO8_LE((p), (uint32_t)((v) )); \
60 U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); \
63 #define ROTL64(v, s) \
64 ((v) << (s)) | ((v) >> (64 - (s)))
66 #define ROTL64_TO(v, s) ((v) = ROTL64((v), (s)))
68 #define ADD64_TO(v, s) ((v) += (s))
69 #define XOR64_TO(v, s) ((v) ^= (s))
70 #define XOR64_INT(v, x) ((v) ^= (x))
72 #define U8TO64_LE(p) u8to64_le(p)
82 #define U64TO8_LE(p, v) u64to8_le(p, v)
90 #define ROTL64_TO(v, s) ((s) > 32 ? rotl64_swap(rotl64_to(&(v), (s) - 32)) : \
91 (s) == 32 ? rotl64_swap(&(v)) : rotl64_to(&(v), (s)))
95 uint32_t uhi = (v->hi <<
s) | (v->lo >> (32 - s));
96 uint32_t ulo = (v->lo <<
s) | (v->hi >> (32 - s));
111 #define ADD64_TO(v, s) add64_to(&(v), (s))
117 if (v->lo < s.lo) v->hi++;
121 #define XOR64_TO(v, s) xor64_to(&(v), (s))
130 #define XOR64_INT(v, x) ((v).lo ^= (x))
137 #define sip_init_state sip_init_state_bin.u64
139 #if SIP_HASH_STREAMING
157 #define SIP_COMPRESS(v0, v1, v2, v3) \
159 ADD64_TO((v0), (v1)); \
160 ADD64_TO((v2), (v3)); \
161 ROTL64_TO((v1), 13); \
162 ROTL64_TO((v3), 16); \
163 XOR64_TO((v1), (v0)); \
164 XOR64_TO((v3), (v2)); \
165 ROTL64_TO((v0), 32); \
166 ADD64_TO((v2), (v1)); \
167 ADD64_TO((v0), (v3)); \
168 ROTL64_TO((v1), 17); \
169 ROTL64_TO((v3), 21); \
170 XOR64_TO((v1), (v2)); \
171 XOR64_TO((v3), (v0)); \
172 ROTL64_TO((v2), 32); \
175 #if SIP_HASH_STREAMING
181 for (v = 0; v < 4; v++) {
183 printf(
"v%d: %" PRIx64
"\n", v, state->
v[v]);
185 printf(
"v%d: %" PRIx32
"%.8" PRIx32
"\n", v, state->
v[v].hi, state->
v[v].lo);
209 for (i = 0; i <
n; i++) {
228 if (!state->
buflen)
return;
260 end = data64 + (len /
sizeof(
uint64_t));
262 #if BYTE_ORDER == LITTLE_ENDIAN
263 while (data64 != end) {
266 #elif BYTE_ORDER == BIG_ENDIAN
286 state->
buf[
i] = 0x00;
305 *digest = state->
v[0];
388 #define SIP_2_ROUND(m, v0, v1, v2, v3) \
390 XOR64_TO((v3), (m)); \
391 SIP_COMPRESS(v0, v1, v2, v3); \
392 SIP_COMPRESS(v0, v1, v2, v3); \
393 XOR64_TO((v0), (m)); \
412 #if BYTE_ORDER == LITTLE_ENDIAN && UNALIGNED_WORD_ACCESS
420 #elif BYTE_ORDER == BIG_ENDIAN
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
456 #elif BYTE_ORDER == BIG_ENDIAN
static uint64_t * rotl64_to(uint64_t *v, unsigned int s)
const sip_interface * methods
int sip_hash_final_integer(sip_hash *h, uint64_t *digest)
void(* update)(sip_state *s, const uint8_t *data, size_t len)
void(* final)(sip_state *s, uint64_t *digest)
uint8_t buf[sizeof(uint64_t)]
static void int_sip_final(sip_state *state, uint64_t *digest)
int sip_hash_update(sip_hash *h, const uint8_t *msg, size_t len)
static const sip_interface sip_methods
static uint64_t u8to64_le(const uint8_t *p)
static uint64_t * xor64_to(uint64_t *v, const uint64_t s)
void(* init)(sip_state *s, const uint8_t *key)
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)
static void int_sip_post_update(sip_state *state, const uint8_t *data, size_t len)
unsigned long long uint64_t
static void int_sip_round(sip_state *state, int n)
static void int_sip_update(sip_state *state, const uint8_t *data, size_t len)
static void int_sip_pad_final_block(sip_state *state)
#define SIP_2_ROUND(m, v0, v1, v2, v3)
static uint64_t * add64_to(uint64_t *v, const uint64_t s)
static uint64_t * rotl64_swap(uint64_t *v)
static void u64to8_le(uint8_t *p, uint64_t v)
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)
static void int_sip_pre_update(sip_state *state, const uint8_t **pdata, size_t *plen)
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)
static void int_sip_dump(sip_state *state)
static void int_sip_update_block(sip_state *state, uint64_t m)
#define SIP_COMPRESS(v0, v1, v2, v3)
static void int_sip_init(sip_state *state, const uint8_t *key)
static union @68 sip_init_state_bin