Botan  2.11.0
Crypto and TLS for C++11
siphash.cpp
Go to the documentation of this file.
1 /*
2 * SipHash
3 * (C) 2014,2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/siphash.h>
9 #include <botan/rotate.h>
10 
11 namespace Botan {
12 
13 namespace {
14 
15 void SipRounds(uint64_t M, secure_vector<uint64_t>& V, size_t r)
16  {
17  uint64_t V0 = V[0], V1 = V[1], V2 = V[2], V3 = V[3];
18 
19  V3 ^= M;
20  for(size_t i = 0; i != r; ++i)
21  {
22  V0 += V1; V2 += V3;
23  V1 = rotl<13>(V1);
24  V3 = rotl<16>(V3);
25  V1 ^= V0; V3 ^= V2;
26  V0 = rotl<32>(V0);
27 
28  V2 += V1; V0 += V3;
29  V1 = rotl<17>(V1);
30  V3 = rotl<21>(V3);
31  V1 ^= V2; V3 ^= V0;
32  V2 = rotl<32>(V2);
33  }
34  V0 ^= M;
35 
36  V[0] = V0; V[1] = V1; V[2] = V2; V[3] = V3;
37  }
38 
39 }
40 
41 void SipHash::add_data(const uint8_t input[], size_t length)
42  {
43  verify_key_set(m_V.empty() == false);
44 
45  // SipHash counts the message length mod 256
46  m_words += static_cast<uint8_t>(length);
47 
48  if(m_mbuf_pos)
49  {
50  while(length && m_mbuf_pos != 8)
51  {
52  m_mbuf = (m_mbuf >> 8) | (static_cast<uint64_t>(input[0]) << 56);
53  ++m_mbuf_pos;
54  ++input;
55  length--;
56  }
57 
58  if(m_mbuf_pos == 8)
59  {
60  SipRounds(m_mbuf, m_V, m_C);
61  m_mbuf_pos = 0;
62  m_mbuf = 0;
63  }
64  }
65 
66  while(length >= 8)
67  {
68  SipRounds(load_le<uint64_t>(input, 0), m_V, m_C);
69  input += 8;
70  length -= 8;
71  }
72 
73  for(size_t i = 0; i != length; ++i)
74  {
75  m_mbuf = (m_mbuf >> 8) | (static_cast<uint64_t>(input[i]) << 56);
76  m_mbuf_pos++;
77  }
78  }
79 
80 void SipHash::final_result(uint8_t mac[])
81  {
82  verify_key_set(m_V.empty() == false);
83 
84  if(m_mbuf_pos == 0)
85  {
86  m_mbuf = (static_cast<uint64_t>(m_words) << 56);
87  }
88  else if(m_mbuf_pos < 8)
89  {
90  m_mbuf = (m_mbuf >> (64-m_mbuf_pos*8)) | (static_cast<uint64_t>(m_words) << 56);
91  }
92 
93  SipRounds(m_mbuf, m_V, m_C);
94 
95  m_V[2] ^= 0xFF;
96  SipRounds(0, m_V, m_D);
97 
98  const uint64_t X = m_V[0] ^ m_V[1] ^ m_V[2] ^ m_V[3];
99 
100  store_le(X, mac);
101 
102  clear();
103  }
104 
105 void SipHash::key_schedule(const uint8_t key[], size_t)
106  {
107  const uint64_t K0 = load_le<uint64_t>(key, 0);
108  const uint64_t K1 = load_le<uint64_t>(key, 1);
109 
110  m_V.resize(4);
111  m_V[0] = K0 ^ 0x736F6D6570736575;
112  m_V[1] = K1 ^ 0x646F72616E646F6D;
113  m_V[2] = K0 ^ 0x6C7967656E657261;
114  m_V[3] = K1 ^ 0x7465646279746573;
115  }
116 
118  {
119  zap(m_V);
120  m_mbuf = 0;
121  m_mbuf_pos = 0;
122  m_words = 0;
123  }
124 
125 std::string SipHash::name() const
126  {
127  return "SipHash(" + std::to_string(m_C) + "," + std::to_string(m_D) + ")";
128  }
129 
131  {
132  return new SipHash(m_C, m_D);
133  }
134 
135 }
fe X
Definition: ge.cpp:27
void verify_key_set(bool cond) const
Definition: sym_algo.h:89
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:170
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
std::string name() const override
Definition: siphash.cpp:125
SipHash(size_t c=2, size_t d=4)
Definition: siphash.h:18
MessageAuthenticationCode * clone() const override
Definition: siphash.cpp:130
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:235
void clear() override
Definition: siphash.cpp:117
Definition: alg_id.cpp:13
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:452