-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsiphash.h
More file actions
87 lines (63 loc) · 2.8 KB
/
siphash.h
File metadata and controls
87 lines (63 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Header guard
#ifndef SIPHASH_H
#define SIPHASH_H
// Header files
using namespace std;
// Constants
// SipHash keys size
#define SIPHASH_KEYS_SIZE 4
// SipRound rotation
#define SIP_ROUND_ROTATION 21
// Function prototypes
// SipHash-2-4
template<const unsigned int numberOfStates> static inline void sipHash24(uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) *__restrict__ nodes, const uint64_t __attribute__((vector_size(sizeof(uint64_t) * SIPHASH_KEYS_SIZE))) &__restrict__ keys, const uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) *__restrict__ nonces) noexcept;
// SipRound
template<const unsigned int numberOfStates> static inline void sipRound(uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) states[SIPHASH_KEYS_SIZE]) noexcept;
// Supporting function implementation
// SipHash-2-4
template<const unsigned int numberOfStates> void sipHash24(uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) *__restrict__ nodes, const uint64_t __attribute__((vector_size(sizeof(uint64_t) * SIPHASH_KEYS_SIZE))) &__restrict__ keys, const uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) *__restrict__ nonces) noexcept {
// Initialize states
uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) states[SIPHASH_KEYS_SIZE] = {};
// Set states to keys
for(uint_fast8_t i = 0; i < SIPHASH_KEYS_SIZE; ++i) {
states[i] += keys[i];
}
// Perform hash on states
states[3] ^= *nonces;
sipRound<numberOfStates>(states);
sipRound<numberOfStates>(states);
states[0] ^= *nonces;
states[2] ^= 255;
sipRound<numberOfStates>(states);
sipRound<numberOfStates>(states);
sipRound<numberOfStates>(states);
sipRound<numberOfStates>(states);
// Check if edge bits is 32
#if EDGE_BITS == 32
// Get nodes from states
*nodes = states[0] ^ states[1] ^ states[2] ^ states[3];
// Otherwise
#else
// Get nodes from states
*nodes = (states[0] ^ states[1] ^ states[2] ^ states[3]) & NODE_MASK;
#endif
}
// SipRound
template<const unsigned int numberOfStates> void sipRound(uint64_t __attribute__((vector_size(sizeof(uint64_t) * numberOfStates))) states[SIPHASH_KEYS_SIZE]) noexcept {
// Perform SipRound on states
states[0] += states[1];
states[2] += states[3];
states[1] = (states[1] << 13) | (states[1] >> (64 - 13));
states[3] = (states[3] << 16) | (states[3] >> (64 - 16));
states[1] ^= states[0];
states[3] ^= states[2];
states[0] = (states[0] << 32) | (states[0] >> (64 - 32));
states[2] += states[1];
states[0] += states[3];
states[1] = (states[1] << 17) | (states[1] >> (64 - 17));
states[3] = (states[3] << SIP_ROUND_ROTATION) | (states[3] >> (64 - SIP_ROUND_ROTATION));
states[1] ^= states[2];
states[3] ^= states[0];
states[2] = (states[2] << 32) | (states[2] >> (64 - 32));
}
#endif