Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/siphash.h
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 &params);
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 &params)
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