Fabcoin Core  0.16.2
P2P Digital Currency
siphash.h
Go to the documentation of this file.
1 // siphash.h - written and placed in public domain by Jeffrey Walton.
2 // Copyright assigned to Crypto++ project.
3 
26 
27 #ifndef CRYPTOPP_SIPHASH_H
28 #define CRYPTOPP_SIPHASH_H
29 
30 #include "cryptlib.h"
31 #include "secblock.h"
32 #include "misc.h"
33 
35 
36 template <bool T_128bit>
40 class SipHash_Info : public FixedKeyLength<16>
41 {
42 public:
43  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "SipHash";}
44  CRYPTOPP_CONSTANT(DIGESTSIZE = (T_128bit ? 16 : 8))
45 };
46 
52 template <unsigned int C, unsigned int D, bool T_128bit>
53 class SipHash_Base : public MessageAuthenticationCode, public SipHash_Info<T_128bit>
54 {
55 public:
56  static std::string StaticAlgorithmName() {
57  return std::string(SipHash_Info<T_128bit>::StaticAlgorithmName())+"-"+IntToString(C)+"-"+IntToString(D);
58  }
59 
60  virtual unsigned int DigestSize() const
62  virtual size_t MinKeyLength() const
64  virtual size_t MaxKeyLength() const
66  virtual size_t DefaultKeyLength() const
68  virtual size_t GetValidKeyLength(size_t keylength) const
70  virtual IV_Requirement IVRequirement() const
72  virtual unsigned int IVSize() const
73  {return 0;}
74  virtual unsigned int OptimalBlockSize() const
75  {return sizeof(word64);}
76  virtual unsigned int OptimalDataAlignment () const
77  {return GetAlignmentOf<word64>();}
78 
79  virtual void Update(const byte *input, size_t length);
80  virtual void TruncatedFinal(byte *digest, size_t digestSize);
81 
82 protected:
83 
84  virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
85  virtual void Restart();
86 
87  inline void SIPROUND()
88  {
89  m_v[0] += m_v[1];
90  m_v[1] = rotlFixed(m_v[1], 13U);
91  m_v[1] ^= m_v[0];
92  m_v[0] = rotlFixed(m_v[0], 32U);
93  m_v[2] += m_v[3];
94  m_v[3] = rotlFixed(m_v[3], 16U);
95  m_v[3] ^= m_v[2];
96  m_v[0] += m_v[3];
97  m_v[3] = rotlFixed(m_v[3], 21U);
98  m_v[3] ^= m_v[0];
99  m_v[2] += m_v[1];
100  m_v[1] = rotlFixed(m_v[1], 17U);
101  m_v[1] ^= m_v[2];
102  m_v[2] = rotlFixed(m_v[2], 32U);
103  }
104 
105 private:
109 
110  // Tail bytes
112  size_t m_idx;
113 };
114 
140 template <unsigned int C=2, unsigned int D=4, bool T_128bit=false>
141 class SipHash : public SipHash_Base<C, D, T_128bit>
142 {
143 public:
146  {this->UncheckedSetKey(NULL, 0, g_nullNameValuePairs);}
150  SipHash(const byte *key, unsigned int length)
151  {this->UncheckedSetKey(key, length, g_nullNameValuePairs);}
152 };
153 
154 template <unsigned int C, unsigned int D, bool T_128bit>
155 void SipHash_Base<C,D,T_128bit>::Update(const byte *input, size_t length)
156 {
157  CRYPTOPP_ASSERT((input && length) || !length);
158  if (!length) return;
159 
160  if (m_idx)
161  {
162  size_t head = STDMIN(size_t(8U-m_idx), length);
163  memcpy(m_acc+m_idx, input, head);
164  m_idx += head; input += head; length -= head;
165 
166  if (m_idx == 8)
167  {
168  word64 m = GetWord<word64>(true, LITTLE_ENDIAN_ORDER, m_acc);
169  m_v[3] ^= m;
170  for (unsigned int i = 0; i < C; ++i)
171  SIPROUND();
172 
173  m_v[0] ^= m;
174  m_b[0] += 8;
175 
176  m_idx = 0;
177  }
178  }
179 
180  while (length >= 8)
181  {
182  word64 m = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, input);
183  m_v[3] ^= m;
184  for (unsigned int i = 0; i < C; ++i)
185  SIPROUND();
186 
187  m_v[0] ^= m;
188  m_b[0] += 8;
189 
190  input += 8;
191  length -= 8;
192  }
193 
194  CRYPTOPP_ASSERT(length < 8);
195  size_t tail = length % 8;
196  if (tail)
197  {
198  memcpy(m_acc+m_idx, input, tail);
199  m_idx += tail;
200  }
201 }
202 
203 template <unsigned int C, unsigned int D, bool T_128bit>
204 void SipHash_Base<C,D,T_128bit>::TruncatedFinal(byte *digest, size_t digestSize)
205 {
206  CRYPTOPP_ASSERT(digest); // Pointer is valid
207 
208  ThrowIfInvalidTruncatedSize(digestSize);
209 
210  // The high octet holds length and is digested mod 256
211  m_b[0] += m_idx; m_b[0] <<= 56U;
212  switch (m_idx)
213  {
214  // all fall through
215  case 7:
216  m_b[0] |= ((word64)m_acc[6]) << 48;
217  case 6:
218  m_b[0] |= ((word64)m_acc[5]) << 40;
219  case 5:
220  m_b[0] |= ((word64)m_acc[4]) << 32;
221  case 4:
222  m_b[0] |= ((word64)m_acc[3]) << 24;
223  case 3:
224  m_b[0] |= ((word64)m_acc[2]) << 16;
225  case 2:
226  m_b[0] |= ((word64)m_acc[1]) << 8;
227  case 1:
228  m_b[0] |= ((word64)m_acc[0]);
229  case 0:
230  break;
231  }
232 
233  m_v[3] ^= m_b[0];
234 
235  for (unsigned int i=0; i<C; i++)
236  SIPROUND();
237 
238  m_v[0] ^= m_b[0];
239 
240  if (T_128bit)
241  m_v[2] ^= 0xee;
242  else
243  m_v[2] ^= 0xff;
244 
245  for (unsigned int i=0; i<D; i++)
246  SIPROUND();
247 
248  m_b[0] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3];
250 
251  if (T_128bit)
252  {
253  m_v[1] ^= 0xdd;
254  for (unsigned int i = 0; i<D; ++i)
255  SIPROUND();
256 
257  m_b[1] = m_v[0] ^ m_v[1] ^ m_v[2] ^ m_v[3];
259  }
260 
261  memcpy_s(digest, digestSize, m_b.begin(), STDMIN(digestSize, (size_t)SipHash_Info<T_128bit>::DIGESTSIZE));
262  Restart();
263 }
264 
265 template <unsigned int C, unsigned int D, bool T_128bit>
266 void SipHash_Base<C,D,T_128bit>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
267 {
268  CRYPTOPP_UNUSED(params);
269  if (key && length)
270  {
271  m_k[0] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key);
272  m_k[1] = GetWord<word64>(false, LITTLE_ENDIAN_ORDER, key+8);
273  }
274  else
275  {
276  // Avoid Coverity finding
277  m_k[0] = m_k[1] = 0;
278  }
279  Restart();
280 }
281 
282 template <unsigned int C, unsigned int D, bool T_128bit>
284 {
285  m_v[0] = W64LIT(0x736f6d6570736575);
286  m_v[1] = W64LIT(0x646f72616e646f6d);
287  m_v[2] = W64LIT(0x6c7967656e657261);
288  m_v[3] = W64LIT(0x7465646279746573);
289 
290  m_v[3] ^= m_k[1];
291  m_v[2] ^= m_k[0];
292  m_v[1] ^= m_k[1];
293  m_v[0] ^= m_k[0];
294 
295  if (T_128bit)
296  {
297  m_v[1] ^= 0xee;
298  }
299 
300  m_idx = 0;
301  m_b[0] = 0;
302 }
303 
305 
306 #endif // CRYPTOPP_SIPHASH_H
SipHash message authentication code information.
Definition: siphash.h:40
Interface for message authentication codes.
Definition: cryptlib.h:1111
Inherited by keyed algorithms with fixed key length.
Definition: seckey.h:127
SipHash message authentication code base class.
Definition: siphash.h:53
uint8_t byte
Definition: Common.h:57
virtual unsigned int OptimalBlockSize() const
Provides the input block size most efficient for this hash.
Definition: siphash.h:74
Utility functions for the Crypto++ library.
#define CRYPTOPP_STATIC_CONSTEXPR
Definition: config.h:892
SipHash message authentication code.
Definition: siphash.h:141
virtual unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: siphash.h:60
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1263
virtual size_t MinKeyLength() const
Returns smallest valid key length.
Definition: siphash.h:62
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
Abstract base classes that provide a uniform interface to this library.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Definition: misc.h:366
virtual void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: siphash.h:155
FixedSizeSecBlock< byte, 8 > m_acc
Definition: siphash.h:111
The object does not use an IV.
Definition: cryptlib.h:608
FixedSizeSecBlock< word64, 2 > m_k
Definition: siphash.h:107
static std::string StaticAlgorithmName()
Definition: siphash.h:56
virtual unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
Definition: siphash.h:76
byte order is little-endian
Definition: cryptlib.h:126
size_t m_idx
Definition: siphash.h:112
void ThrowIfInvalidTruncatedSize(size_t size) const
Validates a truncated digest size.
Definition: cryptlib.cpp:416
Classes and functions for secure memory allocations.
SipHash(const byte *key, unsigned int length)
Create a SipHash.
Definition: siphash.h:150
CRYPTOPP_STATIC_CONSTEXPR const char * StaticAlgorithmName()
Definition: siphash.h:43
virtual size_t GetValidKeyLength(size_t keylength) const
Returns a valid key length for the algorithm.
Definition: siphash.h:68
virtual unsigned int IVSize() const
Returns length of the IV accepted by this object.
Definition: siphash.h:72
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:1807
#define W64LIT(x)
Definition: config.h:241
unsigned long long word64
Definition: config.h:240
#define CRYPTOPP_CONSTANT(x)
Definition: config.h:540
virtual void Restart()
Restart the hash.
Definition: siphash.h:283
FixedSizeSecBlock< word64, 4 > m_v
Definition: siphash.h:106
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.cpp:76
virtual size_t DefaultKeyLength() const
Returns default key length.
Definition: siphash.h:66
virtual size_t MaxKeyLength() const
Returns largest valid key length.
Definition: siphash.h:64
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:499
IV_Requirement
Secure IVs requirements as enumerated values.
Definition: cryptlib.h:598
void * memcpy(void *a, const void *b, size_t c)
#define CRYPTOPP_UNUSED(x)
Definition: config.h:741
FixedSizeSecBlock< word64, 2 > m_b
Definition: siphash.h:108
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:539
SipHash()
Create a SipHash.
Definition: siphash.h:145
virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
Sets the key for this object without performing parameter validation.
Definition: siphash.h:266
#define NAMESPACE_END
Definition: config.h:201
virtual IV_Requirement IVRequirement() const
Minimal requirement for secure IVs.
Definition: siphash.h:70
void SIPROUND()
Definition: siphash.h:87
virtual void TruncatedFinal(byte *digest, size_t digestSize)
Computes the hash of the current message.
Definition: siphash.h:204
Interface for retrieving values given their names.
Definition: cryptlib.h:279