Line | Count | Source (jump to first uncovered line) |
1 | | // siphash.h - written and placed in public domain by Jeffrey Walton. |
2 | | |
3 | | /// \file siphash.h |
4 | | /// \brief Classes for SipHash message authentication code |
5 | | /// \details SipHash computes a 64-bit or 128-bit message authentication code from a variable-length |
6 | | /// message and 128-bit secret key. It was designed to be efficient even for short inputs, with |
7 | | /// performance comparable to non-cryptographic hash functions. |
8 | | /// \details To create a SipHash-2-4 object with a 64-bit MAC use code similar to the following. |
9 | | /// <pre> SecByteBlock key(16); |
10 | | /// prng.GenerateBlock(key, key.size()); |
11 | | /// |
12 | | /// SipHash<2,4,false> hash(key, key.size()); |
13 | | /// hash.Update(...); |
14 | | /// hash.Final(...);</pre> |
15 | | /// \details To create a SipHash-2-4 object with a 128-bit MAC use code similar to the following. |
16 | | /// <pre> SecByteBlock key(16); |
17 | | /// prng.GenerateBlock(key, key.size()); |
18 | | /// |
19 | | /// SipHash<2,4,true> hash(key, key.size()); |
20 | | /// hash.Update(...); |
21 | | /// hash.Final(...);</pre> |
22 | | /// \sa Jean-Philippe Aumasson and Daniel J. Bernstein <A HREF="http://131002.net/siphash/siphash.pdf">SipHash: |
23 | | /// a fast short-input PRF</A> |
24 | | /// \since Crypto++ 6.0 |
25 | | |
26 | | #ifndef CRYPTOPP_SIPHASH_H |
27 | | #define CRYPTOPP_SIPHASH_H |
28 | | |
29 | | #include "cryptlib.h" |
30 | | #include "secblock.h" |
31 | | #include "seckey.h" |
32 | | #include "misc.h" |
33 | | |
34 | | NAMESPACE_BEGIN(CryptoPP) |
35 | | |
36 | | /// \brief SipHash message authentication code information |
37 | | /// \tparam T_128bit flag indicating 128-bit (true) versus 64-bit (false) digest size |
38 | | template <bool T_128bit> |
39 | | class SipHash_Info : public FixedKeyLength<16> |
40 | | { |
41 | | public: |
42 | | CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SipHash";} |
43 | | CRYPTOPP_CONSTANT(DIGESTSIZE = (T_128bit ? 16 : 8)); |
44 | | }; |
45 | | |
46 | | /// \brief SipHash message authentication code base class |
47 | | /// \tparam C the number of compression rounds |
48 | | /// \tparam D the number of finalization rounds |
49 | | /// \tparam T_128bit flag indicating 128-bit (true) versus 64-bit (false) digest size |
50 | | template <unsigned int C, unsigned int D, bool T_128bit> |
51 | | class SipHash_Base : public MessageAuthenticationCode, public SipHash_Info<T_128bit> |
52 | | { |
53 | | public: |
54 | | static std::string StaticAlgorithmName() { |
55 | | return std::string(SipHash_Info<T_128bit>::StaticAlgorithmName())+"-"+IntToString(C)+"-"+IntToString(D); |
56 | | } |
57 | | |
58 | 35 | virtual ~SipHash_Base() {} CryptoPP::SipHash_Base<2u, 4u, false>::~SipHash_Base() Line | Count | Source | 58 | 19 | virtual ~SipHash_Base() {} |
CryptoPP::SipHash_Base<2u, 4u, true>::~SipHash_Base() Line | Count | Source | 58 | 16 | virtual ~SipHash_Base() {} |
|
59 | | |
60 | 35 | SipHash_Base() : m_idx(0) {} CryptoPP::SipHash_Base<2u, 4u, false>::SipHash_Base() Line | Count | Source | 60 | 19 | SipHash_Base() : m_idx(0) {} |
CryptoPP::SipHash_Base<2u, 4u, true>::SipHash_Base() Line | Count | Source | 60 | 16 | SipHash_Base() : m_idx(0) {} |
|
61 | | |
62 | | virtual unsigned int DigestSize() const |
63 | 24 | {return SipHash_Info<T_128bit>::DIGESTSIZE;} CryptoPP::SipHash_Base<2u, 4u, false>::DigestSize() const Line | Count | Source | 63 | 10 | {return SipHash_Info<T_128bit>::DIGESTSIZE;} |
CryptoPP::SipHash_Base<2u, 4u, true>::DigestSize() const Line | Count | Source | 63 | 14 | {return SipHash_Info<T_128bit>::DIGESTSIZE;} |
|
64 | | virtual size_t MinKeyLength() const |
65 | 0 | {return SipHash_Info<T_128bit>::MIN_KEYLENGTH;} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::MinKeyLength() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::MinKeyLength() const |
66 | | virtual size_t MaxKeyLength() const |
67 | 0 | {return SipHash_Info<T_128bit>::MAX_KEYLENGTH;} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::MaxKeyLength() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::MaxKeyLength() const |
68 | | virtual size_t DefaultKeyLength() const |
69 | 0 | {return SipHash_Info<T_128bit>::DEFAULT_KEYLENGTH;} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::DefaultKeyLength() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::DefaultKeyLength() const |
70 | | virtual size_t GetValidKeyLength(size_t keylength) const |
71 | 35 | {CRYPTOPP_UNUSED(keylength); return SipHash_Info<T_128bit>::DEFAULT_KEYLENGTH;} CryptoPP::SipHash_Base<2u, 4u, false>::GetValidKeyLength(unsigned long) const Line | Count | Source | 71 | 19 | {CRYPTOPP_UNUSED(keylength); return SipHash_Info<T_128bit>::DEFAULT_KEYLENGTH;} |
CryptoPP::SipHash_Base<2u, 4u, true>::GetValidKeyLength(unsigned long) const Line | Count | Source | 71 | 16 | {CRYPTOPP_UNUSED(keylength); return SipHash_Info<T_128bit>::DEFAULT_KEYLENGTH;} |
|
72 | | virtual IV_Requirement IVRequirement() const |
73 | 0 | {return SimpleKeyingInterface::NOT_RESYNCHRONIZABLE;} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::IVRequirement() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::IVRequirement() const |
74 | | virtual unsigned int IVSize() const |
75 | 0 | {return 0;} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::IVSize() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::IVSize() const |
76 | | virtual unsigned int OptimalBlockSize() const |
77 | 0 | {return sizeof(word64);} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::OptimalBlockSize() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::OptimalBlockSize() const |
78 | | virtual unsigned int OptimalDataAlignment () const |
79 | 0 | {return GetAlignmentOf<word64>();} Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, false>::OptimalDataAlignment() const Unexecuted instantiation: CryptoPP::SipHash_Base<2u, 4u, true>::OptimalDataAlignment() const |
80 | | |
81 | | virtual void Update(const byte *input, size_t length); |
82 | | virtual void TruncatedFinal(byte *digest, size_t digestSize); |
83 | | |
84 | | protected: |
85 | | |
86 | | virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); |
87 | | virtual void Restart(); |
88 | | |
89 | | inline void SIPROUND() |
90 | 12.0k | { |
91 | 12.0k | m_v[0] += m_v[1]; |
92 | 12.0k | m_v[1] = rotlConstant<13>(m_v[1]); |
93 | 12.0k | m_v[1] ^= m_v[0]; |
94 | 12.0k | m_v[0] = rotlConstant<32>(m_v[0]); |
95 | 12.0k | m_v[2] += m_v[3]; |
96 | 12.0k | m_v[3] = rotlConstant<16>(m_v[3]); |
97 | 12.0k | m_v[3] ^= m_v[2]; |
98 | 12.0k | m_v[0] += m_v[3]; |
99 | 12.0k | m_v[3] = rotlConstant<21>(m_v[3]); |
100 | 12.0k | m_v[3] ^= m_v[0]; |
101 | 12.0k | m_v[2] += m_v[1]; |
102 | 12.0k | m_v[1] = rotlConstant<17>(m_v[1]); |
103 | 12.0k | m_v[1] ^= m_v[2]; |
104 | 12.0k | m_v[2] = rotlConstant<32>(m_v[2]); |
105 | 12.0k | } CryptoPP::SipHash_Base<2u, 4u, false>::SIPROUND() Line | Count | Source | 90 | 1.78k | { | 91 | 1.78k | m_v[0] += m_v[1]; | 92 | 1.78k | m_v[1] = rotlConstant<13>(m_v[1]); | 93 | 1.78k | m_v[1] ^= m_v[0]; | 94 | 1.78k | m_v[0] = rotlConstant<32>(m_v[0]); | 95 | 1.78k | m_v[2] += m_v[3]; | 96 | 1.78k | m_v[3] = rotlConstant<16>(m_v[3]); | 97 | 1.78k | m_v[3] ^= m_v[2]; | 98 | 1.78k | m_v[0] += m_v[3]; | 99 | 1.78k | m_v[3] = rotlConstant<21>(m_v[3]); | 100 | 1.78k | m_v[3] ^= m_v[0]; | 101 | 1.78k | m_v[2] += m_v[1]; | 102 | 1.78k | m_v[1] = rotlConstant<17>(m_v[1]); | 103 | 1.78k | m_v[1] ^= m_v[2]; | 104 | 1.78k | m_v[2] = rotlConstant<32>(m_v[2]); | 105 | 1.78k | } |
CryptoPP::SipHash_Base<2u, 4u, true>::SIPROUND() Line | Count | Source | 90 | 10.2k | { | 91 | 10.2k | m_v[0] += m_v[1]; | 92 | 10.2k | m_v[1] = rotlConstant<13>(m_v[1]); | 93 | 10.2k | m_v[1] ^= m_v[0]; | 94 | 10.2k | m_v[0] = rotlConstant<32>(m_v[0]); | 95 | 10.2k | m_v[2] += m_v[3]; | 96 | 10.2k | m_v[3] = rotlConstant<16>(m_v[3]); | 97 | 10.2k | m_v[3] ^= m_v[2]; | 98 | 10.2k | m_v[0] += m_v[3]; | 99 | 10.2k | m_v[3] = rotlConstant<21>(m_v[3]); | 100 | 10.2k | m_v[3] ^= m_v[0]; | 101 | 10.2k | m_v[2] += m_v[1]; | 102 | 10.2k | m_v[1] = rotlConstant<17>(m_v[1]); | 103 | 10.2k | m_v[1] ^= m_v[2]; | 104 | 10.2k | m_v[2] = rotlConstant<32>(m_v[2]); | 105 | 10.2k | } |
|
106 | | |
107 | | private: |
108 | | FixedSizeSecBlock<word64, 4> m_v; |
109 | | FixedSizeSecBlock<word64, 2> m_k; |
110 | | FixedSizeSecBlock<word64, 2> m_b; |
111 | | |
112 | | // Tail bytes |
113 | | FixedSizeSecBlock<byte, 8> m_acc; |
114 | | size_t m_idx; |
115 | | }; |
116 | | |
117 | | /// \brief SipHash message authentication code |
118 | | /// \tparam C the number of compression rounds |
119 | | /// \tparam D the number of finalization rounds |
120 | | /// \tparam T_128bit flag indicating 128-bit (true) versus 64-bit (false) digest size |
121 | | /// \details SipHash computes a 64-bit or 128-bit message authentication code from a variable-length |
122 | | /// message and 128-bit secret key. It was designed to be efficient even for short inputs, with |
123 | | /// performance comparable to non-cryptographic hash functions. |
124 | | /// \details To create a SipHash-2-4 object with a 64-bit MAC use code similar to the following. |
125 | | /// <pre> SecByteBlock key(16); |
126 | | /// prng.GenerateBlock(key, key.size()); |
127 | | /// |
128 | | /// SipHash<2,4,false> hash(key, key.size()); |
129 | | /// hash.Update(...); |
130 | | /// hash.Final(...);</pre> |
131 | | /// \details To create a SipHash-2-4 object with a 128-bit MAC use code similar to the following. |
132 | | /// <pre> SecByteBlock key(16); |
133 | | /// prng.GenerateBlock(key, key.size()); |
134 | | /// |
135 | | /// SipHash<2,4,true> hash(key, key.size()); |
136 | | /// hash.Update(...); |
137 | | /// hash.Final(...);</pre> |
138 | | /// \sa Jean-Philippe Aumasson and Daniel J. Bernstein <A HREF="http://131002.net/siphash/siphash.pdf">SipHash: |
139 | | /// a fast short-input PRF</A> |
140 | | /// \since Crypto++ 6.0 |
141 | | template <unsigned int C=2, unsigned int D=4, bool T_128bit=false> |
142 | | class SipHash : public SipHash_Base<C, D, T_128bit> |
143 | | { |
144 | | public: |
145 | | /// \brief Create a SipHash |
146 | | SipHash() |
147 | | {this->UncheckedSetKey(NULLPTR, 0, g_nullNameValuePairs);} |
148 | | /// \brief Create a SipHash |
149 | | /// \param key a byte array used to key the cipher |
150 | | /// \param length the size of the byte array, in bytes |
151 | | SipHash(const byte *key, unsigned int length) |
152 | 35 | {this->ThrowIfInvalidKeyLength(length); |
153 | 35 | this->UncheckedSetKey(key, length, g_nullNameValuePairs);} CryptoPP::SipHash<2u, 4u, false>::SipHash(unsigned char const*, unsigned int) Line | Count | Source | 152 | 19 | {this->ThrowIfInvalidKeyLength(length); | 153 | 19 | this->UncheckedSetKey(key, length, g_nullNameValuePairs);} |
CryptoPP::SipHash<2u, 4u, true>::SipHash(unsigned char const*, unsigned int) Line | Count | Source | 152 | 16 | {this->ThrowIfInvalidKeyLength(length); | 153 | 16 | this->UncheckedSetKey(key, length, g_nullNameValuePairs);} |
|
154 | | }; |
155 | | |
156 | | template <unsigned int C, unsigned int D, bool T_128bit> |
157 | | void SipHash_Base<C,D,T_128bit>::Update(const byte *input, size_t length) |
158 | 658 | { |
159 | 658 | CRYPTOPP_ASSERT((input && length) || !length); |
160 | 658 | if (!length) return; |
161 | | |
162 | 85 | if (m_idx) |
163 | 64 | { |
164 | 64 | size_t head = STDMIN(size_t(8U-m_idx), length); |
165 | 64 | std::memcpy(m_acc+m_idx, input, head); |
166 | 64 | m_idx += head; input += head; length -= head; |
167 | | |
168 | 64 | if (m_idx == 8) |
169 | 42 | { |
170 | 42 | word64 m = GetWord<word64>(true, LITTLE_ENDIAN_ORDER, m_acc); |
171 | 42 | m_v[3] ^= m; |
172 | 126 | for (unsigned int i = 0; i < C; ++i) |
173 | 84 | SIPROUND(); |
174 | | |
175 | 42 | m_v[0] ^= m; |
176 | 42 | m_b[0] += 8; |
177 | | |
178 | 42 | m_idx = 0; |
179 | 42 | } |
180 | 64 | } |
181 | | |
182 | 6.00k | while (length >= 8) |
183 | 5.91k | { |
184 | 5.91k | word64 m = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, input); |
185 | 5.91k | m_v[3] ^= m; |
186 | 17.7k | for (unsigned int i = 0; i < C; ++i) |
187 | 11.8k | SIPROUND(); |
188 | | |
189 | 5.91k | m_v[0] ^= m; |
190 | 5.91k | m_b[0] += 8; |
191 | | |
192 | 5.91k | input += 8; |
193 | 5.91k | length -= 8; |
194 | 5.91k | } |
195 | | |
196 | 85 | CRYPTOPP_ASSERT(length < 8); |
197 | 85 | size_t tail = length % 8; |
198 | 85 | if (tail) |
199 | 52 | { |
200 | 52 | std::memcpy(m_acc+m_idx, input, tail); |
201 | 52 | m_idx += tail; |
202 | 52 | } |
203 | 85 | } CryptoPP::SipHash_Base<2u, 4u, false>::Update(unsigned char const*, unsigned long) Line | Count | Source | 158 | 172 | { | 159 | 172 | CRYPTOPP_ASSERT((input && length) || !length); | 160 | 172 | if (!length) return; | 161 | | | 162 | 38 | if (m_idx) | 163 | 26 | { | 164 | 26 | size_t head = STDMIN(size_t(8U-m_idx), length); | 165 | 26 | std::memcpy(m_acc+m_idx, input, head); | 166 | 26 | m_idx += head; input += head; length -= head; | 167 | | | 168 | 26 | if (m_idx == 8) | 169 | 20 | { | 170 | 20 | word64 m = GetWord<word64>(true, LITTLE_ENDIAN_ORDER, m_acc); | 171 | 20 | m_v[3] ^= m; | 172 | 60 | for (unsigned int i = 0; i < C; ++i) | 173 | 40 | SIPROUND(); | 174 | | | 175 | 20 | m_v[0] ^= m; | 176 | 20 | m_b[0] += 8; | 177 | | | 178 | 20 | m_idx = 0; | 179 | 20 | } | 180 | 26 | } | 181 | | | 182 | 895 | while (length >= 8) | 183 | 857 | { | 184 | 857 | word64 m = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, input); | 185 | 857 | m_v[3] ^= m; | 186 | 2.57k | for (unsigned int i = 0; i < C; ++i) | 187 | 1.71k | SIPROUND(); | 188 | | | 189 | 857 | m_v[0] ^= m; | 190 | 857 | m_b[0] += 8; | 191 | | | 192 | 857 | input += 8; | 193 | 857 | length -= 8; | 194 | 857 | } | 195 | | | 196 | 38 | CRYPTOPP_ASSERT(length < 8); | 197 | 38 | size_t tail = length % 8; | 198 | 38 | if (tail) | 199 | 25 | { | 200 | 25 | std::memcpy(m_acc+m_idx, input, tail); | 201 | 25 | m_idx += tail; | 202 | 25 | } | 203 | 38 | } |
CryptoPP::SipHash_Base<2u, 4u, true>::Update(unsigned char const*, unsigned long) Line | Count | Source | 158 | 486 | { | 159 | 486 | CRYPTOPP_ASSERT((input && length) || !length); | 160 | 486 | if (!length) return; | 161 | | | 162 | 47 | if (m_idx) | 163 | 38 | { | 164 | 38 | size_t head = STDMIN(size_t(8U-m_idx), length); | 165 | 38 | std::memcpy(m_acc+m_idx, input, head); | 166 | 38 | m_idx += head; input += head; length -= head; | 167 | | | 168 | 38 | if (m_idx == 8) | 169 | 22 | { | 170 | 22 | word64 m = GetWord<word64>(true, LITTLE_ENDIAN_ORDER, m_acc); | 171 | 22 | m_v[3] ^= m; | 172 | 66 | for (unsigned int i = 0; i < C; ++i) | 173 | 44 | SIPROUND(); | 174 | | | 175 | 22 | m_v[0] ^= m; | 176 | 22 | m_b[0] += 8; | 177 | | | 178 | 22 | m_idx = 0; | 179 | 22 | } | 180 | 38 | } | 181 | | | 182 | 5.10k | while (length >= 8) | 183 | 5.05k | { | 184 | 5.05k | word64 m = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, input); | 185 | 5.05k | m_v[3] ^= m; | 186 | 15.1k | for (unsigned int i = 0; i < C; ++i) | 187 | 10.1k | SIPROUND(); | 188 | | | 189 | 5.05k | m_v[0] ^= m; | 190 | 5.05k | m_b[0] += 8; | 191 | | | 192 | 5.05k | input += 8; | 193 | 5.05k | length -= 8; | 194 | 5.05k | } | 195 | | | 196 | 47 | CRYPTOPP_ASSERT(length < 8); | 197 | 47 | size_t tail = length % 8; | 198 | 47 | if (tail) | 199 | 27 | { | 200 | 27 | std::memcpy(m_acc+m_idx, input, tail); | 201 | 27 | m_idx += tail; | 202 | 27 | } | 203 | 47 | } |
|
204 | | |
205 | | template <unsigned int C, unsigned int D, bool T_128bit> |
206 | | void SipHash_Base<C,D,T_128bit>::TruncatedFinal(byte *digest, size_t digestSize) |
207 | 12 | { |
208 | 12 | CRYPTOPP_ASSERT(digest); // Pointer is valid |
209 | | |
210 | 12 | ThrowIfInvalidTruncatedSize(digestSize); |
211 | | |
212 | | // The high octet holds length and is digested mod 256 |
213 | 12 | m_b[0] += m_idx; m_b[0] <<= 56U; |
214 | 12 | switch (m_idx) |
215 | 12 | { |
216 | 3 | case 7: |
217 | 3 | m_b[0] |= ((word64)m_acc[6]) << 48; |
218 | | // fall through |
219 | 3 | case 6: |
220 | 3 | m_b[0] |= ((word64)m_acc[5]) << 40; |
221 | | // fall through |
222 | 6 | case 5: |
223 | 6 | m_b[0] |= ((word64)m_acc[4]) << 32; |
224 | | // fall through |
225 | 6 | case 4: |
226 | 6 | m_b[0] |= ((word64)m_acc[3]) << 24; |
227 | | // fall through |
228 | 7 | case 3: |
229 | 7 | m_b[0] |= ((word64)m_acc[2]) << 16; |
230 | | // fall through |
231 | 10 | case 2: |
232 | 10 | m_b[0] |= ((word64)m_acc[1]) << 8; |
233 | | // fall through |
234 | 10 | case 1: |
235 | 10 | m_b[0] |= ((word64)m_acc[0]); |
236 | | // fall through |
237 | 12 | case 0: |
238 | 12 | break; |
239 | 12 | } |
240 | | |
241 | 12 | m_v[3] ^= m_b[0]; |
242 | | |
243 | 36 | for (unsigned int i=0; i<C; i++) |
244 | 24 | SIPROUND(); |
245 | | |
246 | 12 | m_v[0] ^= m_b[0]; |
247 | | |
248 | 12 | if (T_128bit) |
249 | 7 | m_v[2] ^= 0xee; |
250 | 5 | else |
251 | 5 | m_v[2] ^= 0xff; |
252 | | |
253 | 60 | for (unsigned int i=0; i<D; i++) |
254 | 48 | SIPROUND(); |
255 | | |
256 | 12 | m_b[0] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3]; |
257 | 12 | m_b[0] = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, m_b[0]); |
258 | | |
259 | 12 | if (T_128bit) |
260 | 7 | { |
261 | 7 | m_v[1] ^= 0xdd; |
262 | 35 | for (unsigned int i = 0; i<D; ++i) |
263 | 28 | SIPROUND(); |
264 | | |
265 | 7 | m_b[1] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3]; |
266 | 7 | m_b[1] = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, m_b[1]); |
267 | 7 | } |
268 | | |
269 | 12 | memcpy_s(digest, digestSize, m_b.begin(), STDMIN(digestSize, (size_t)SipHash_Info<T_128bit>::DIGESTSIZE)); |
270 | 12 | Restart(); |
271 | 12 | } CryptoPP::SipHash_Base<2u, 4u, false>::TruncatedFinal(unsigned char*, unsigned long) Line | Count | Source | 207 | 5 | { | 208 | 5 | CRYPTOPP_ASSERT(digest); // Pointer is valid | 209 | | | 210 | 5 | ThrowIfInvalidTruncatedSize(digestSize); | 211 | | | 212 | | // The high octet holds length and is digested mod 256 | 213 | 5 | m_b[0] += m_idx; m_b[0] <<= 56U; | 214 | 5 | switch (m_idx) | 215 | 5 | { | 216 | 0 | case 7: | 217 | 0 | m_b[0] |= ((word64)m_acc[6]) << 48; | 218 | | // fall through | 219 | 0 | case 6: | 220 | 0 | m_b[0] |= ((word64)m_acc[5]) << 40; | 221 | | // fall through | 222 | 1 | case 5: | 223 | 1 | m_b[0] |= ((word64)m_acc[4]) << 32; | 224 | | // fall through | 225 | 1 | case 4: | 226 | 1 | m_b[0] |= ((word64)m_acc[3]) << 24; | 227 | | // fall through | 228 | 2 | case 3: | 229 | 2 | m_b[0] |= ((word64)m_acc[2]) << 16; | 230 | | // fall through | 231 | 5 | case 2: | 232 | 5 | m_b[0] |= ((word64)m_acc[1]) << 8; | 233 | | // fall through | 234 | 5 | case 1: | 235 | 5 | m_b[0] |= ((word64)m_acc[0]); | 236 | | // fall through | 237 | 5 | case 0: | 238 | 5 | break; | 239 | 5 | } | 240 | | | 241 | 5 | m_v[3] ^= m_b[0]; | 242 | | | 243 | 15 | for (unsigned int i=0; i<C; i++) | 244 | 10 | SIPROUND(); | 245 | | | 246 | 5 | m_v[0] ^= m_b[0]; | 247 | | | 248 | 5 | if (T_128bit) | 249 | 0 | m_v[2] ^= 0xee; | 250 | 5 | else | 251 | 5 | m_v[2] ^= 0xff; | 252 | | | 253 | 25 | for (unsigned int i=0; i<D; i++) | 254 | 20 | SIPROUND(); | 255 | | | 256 | 5 | m_b[0] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3]; | 257 | 5 | m_b[0] = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, m_b[0]); | 258 | | | 259 | 5 | if (T_128bit) | 260 | 0 | { | 261 | 0 | m_v[1] ^= 0xdd; | 262 | 0 | for (unsigned int i = 0; i<D; ++i) | 263 | 0 | SIPROUND(); | 264 | |
| 265 | 0 | m_b[1] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3]; | 266 | 0 | m_b[1] = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, m_b[1]); | 267 | 0 | } | 268 | | | 269 | 5 | memcpy_s(digest, digestSize, m_b.begin(), STDMIN(digestSize, (size_t)SipHash_Info<T_128bit>::DIGESTSIZE)); | 270 | 5 | Restart(); | 271 | 5 | } |
CryptoPP::SipHash_Base<2u, 4u, true>::TruncatedFinal(unsigned char*, unsigned long) Line | Count | Source | 207 | 7 | { | 208 | 7 | CRYPTOPP_ASSERT(digest); // Pointer is valid | 209 | | | 210 | 7 | ThrowIfInvalidTruncatedSize(digestSize); | 211 | | | 212 | | // The high octet holds length and is digested mod 256 | 213 | 7 | m_b[0] += m_idx; m_b[0] <<= 56U; | 214 | 7 | switch (m_idx) | 215 | 7 | { | 216 | 3 | case 7: | 217 | 3 | m_b[0] |= ((word64)m_acc[6]) << 48; | 218 | | // fall through | 219 | 3 | case 6: | 220 | 3 | m_b[0] |= ((word64)m_acc[5]) << 40; | 221 | | // fall through | 222 | 5 | case 5: | 223 | 5 | m_b[0] |= ((word64)m_acc[4]) << 32; | 224 | | // fall through | 225 | 5 | case 4: | 226 | 5 | m_b[0] |= ((word64)m_acc[3]) << 24; | 227 | | // fall through | 228 | 5 | case 3: | 229 | 5 | m_b[0] |= ((word64)m_acc[2]) << 16; | 230 | | // fall through | 231 | 5 | case 2: | 232 | 5 | m_b[0] |= ((word64)m_acc[1]) << 8; | 233 | | // fall through | 234 | 5 | case 1: | 235 | 5 | m_b[0] |= ((word64)m_acc[0]); | 236 | | // fall through | 237 | 7 | case 0: | 238 | 7 | break; | 239 | 7 | } | 240 | | | 241 | 7 | m_v[3] ^= m_b[0]; | 242 | | | 243 | 21 | for (unsigned int i=0; i<C; i++) | 244 | 14 | SIPROUND(); | 245 | | | 246 | 7 | m_v[0] ^= m_b[0]; | 247 | | | 248 | 7 | if (T_128bit) | 249 | 7 | m_v[2] ^= 0xee; | 250 | 0 | else | 251 | 0 | m_v[2] ^= 0xff; | 252 | | | 253 | 35 | for (unsigned int i=0; i<D; i++) | 254 | 28 | SIPROUND(); | 255 | | | 256 | 7 | m_b[0] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3]; | 257 | 7 | m_b[0] = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, m_b[0]); | 258 | | | 259 | 7 | if (T_128bit) | 260 | 7 | { | 261 | 7 | m_v[1] ^= 0xdd; | 262 | 35 | for (unsigned int i = 0; i<D; ++i) | 263 | 28 | SIPROUND(); | 264 | | | 265 | 7 | m_b[1] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3]; | 266 | 7 | m_b[1] = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, m_b[1]); | 267 | 7 | } | 268 | | | 269 | 7 | memcpy_s(digest, digestSize, m_b.begin(), STDMIN(digestSize, (size_t)SipHash_Info<T_128bit>::DIGESTSIZE)); | 270 | 7 | Restart(); | 271 | 7 | } |
|
272 | | |
273 | | template <unsigned int C, unsigned int D, bool T_128bit> |
274 | | void SipHash_Base<C,D,T_128bit>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) |
275 | 12 | { |
276 | 12 | CRYPTOPP_UNUSED(params); |
277 | 12 | if (key && length) |
278 | 12 | { |
279 | 12 | m_k[0] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key); |
280 | 12 | m_k[1] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key+8); |
281 | 12 | } |
282 | 0 | else |
283 | 0 | { |
284 | | // Avoid Coverity finding |
285 | 0 | m_k[0] = m_k[1] = 0; |
286 | 0 | } |
287 | 12 | Restart(); |
288 | 12 | } CryptoPP::SipHash_Base<2u, 4u, false>::UncheckedSetKey(unsigned char const*, unsigned int, CryptoPP::NameValuePairs const&) Line | Count | Source | 275 | 5 | { | 276 | 5 | CRYPTOPP_UNUSED(params); | 277 | 5 | if (key && length) | 278 | 5 | { | 279 | 5 | m_k[0] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key); | 280 | 5 | m_k[1] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key+8); | 281 | 5 | } | 282 | 0 | else | 283 | 0 | { | 284 | | // Avoid Coverity finding | 285 | 0 | m_k[0] = m_k[1] = 0; | 286 | 0 | } | 287 | 5 | Restart(); | 288 | 5 | } |
CryptoPP::SipHash_Base<2u, 4u, true>::UncheckedSetKey(unsigned char const*, unsigned int, CryptoPP::NameValuePairs const&) Line | Count | Source | 275 | 7 | { | 276 | 7 | CRYPTOPP_UNUSED(params); | 277 | 7 | if (key && length) | 278 | 7 | { | 279 | 7 | m_k[0] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key); | 280 | 7 | m_k[1] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key+8); | 281 | 7 | } | 282 | 0 | else | 283 | 0 | { | 284 | | // Avoid Coverity finding | 285 | 0 | m_k[0] = m_k[1] = 0; | 286 | 0 | } | 287 | 7 | Restart(); | 288 | 7 | } |
|
289 | | |
290 | | template <unsigned int C, unsigned int D, bool T_128bit> |
291 | | void SipHash_Base<C,D,T_128bit>::Restart () |
292 | 24 | { |
293 | 24 | m_v[0] = W64LIT(0x736f6d6570736575); |
294 | 24 | m_v[1] = W64LIT(0x646f72616e646f6d); |
295 | 24 | m_v[2] = W64LIT(0x6c7967656e657261); |
296 | 24 | m_v[3] = W64LIT(0x7465646279746573); |
297 | | |
298 | 24 | m_v[3] ^= m_k[1]; |
299 | 24 | m_v[2] ^= m_k[0]; |
300 | 24 | m_v[1] ^= m_k[1]; |
301 | 24 | m_v[0] ^= m_k[0]; |
302 | | |
303 | 24 | if (T_128bit) |
304 | 14 | { |
305 | 14 | m_v[1] ^= 0xee; |
306 | 14 | } |
307 | | |
308 | 24 | m_idx = 0; |
309 | 24 | m_b[0] = 0; |
310 | 24 | } CryptoPP::SipHash_Base<2u, 4u, false>::Restart() Line | Count | Source | 292 | 10 | { | 293 | 10 | m_v[0] = W64LIT(0x736f6d6570736575); | 294 | 10 | m_v[1] = W64LIT(0x646f72616e646f6d); | 295 | 10 | m_v[2] = W64LIT(0x6c7967656e657261); | 296 | 10 | m_v[3] = W64LIT(0x7465646279746573); | 297 | | | 298 | 10 | m_v[3] ^= m_k[1]; | 299 | 10 | m_v[2] ^= m_k[0]; | 300 | 10 | m_v[1] ^= m_k[1]; | 301 | 10 | m_v[0] ^= m_k[0]; | 302 | | | 303 | 10 | if (T_128bit) | 304 | 0 | { | 305 | 0 | m_v[1] ^= 0xee; | 306 | 0 | } | 307 | | | 308 | 10 | m_idx = 0; | 309 | 10 | m_b[0] = 0; | 310 | 10 | } |
CryptoPP::SipHash_Base<2u, 4u, true>::Restart() Line | Count | Source | 292 | 14 | { | 293 | 14 | m_v[0] = W64LIT(0x736f6d6570736575); | 294 | 14 | m_v[1] = W64LIT(0x646f72616e646f6d); | 295 | 14 | m_v[2] = W64LIT(0x6c7967656e657261); | 296 | 14 | m_v[3] = W64LIT(0x7465646279746573); | 297 | | | 298 | 14 | m_v[3] ^= m_k[1]; | 299 | 14 | m_v[2] ^= m_k[0]; | 300 | 14 | m_v[1] ^= m_k[1]; | 301 | 14 | m_v[0] ^= m_k[0]; | 302 | | | 303 | 14 | if (T_128bit) | 304 | 14 | { | 305 | 14 | m_v[1] ^= 0xee; | 306 | 14 | } | 307 | | | 308 | 14 | m_idx = 0; | 309 | 14 | m_b[0] = 0; | 310 | 14 | } |
|
311 | | |
312 | | NAMESPACE_END |
313 | | |
314 | | #endif // CRYPTOPP_SIPHASH_H |