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