Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

sha3.cpp
Go to the documentation of this file.
1 /*
2 * SHA-3
3 * (C) 2010,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/sha3.h>
9 #include <botan/loadstor.h>
10 #include <botan/rotate.h>
11 #include <botan/exceptn.h>
12 #include <botan/cpuid.h>
13
14 namespace Botan {
15
16 namespace {
17
18 inline void SHA3_round(uint64_t T[25], const uint64_t A[25], uint64_t RC)
19 {
20 const uint64_t C0 = A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20];
21 const uint64_t C1 = A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21];
22 const uint64_t C2 = A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22];
23 const uint64_t C3 = A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23];
24 const uint64_t C4 = A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24];
25
26 const uint64_t D0 = rotl<1>(C0) ^ C3;
27 const uint64_t D1 = rotl<1>(C1) ^ C4;
28 const uint64_t D2 = rotl<1>(C2) ^ C0;
29 const uint64_t D3 = rotl<1>(C3) ^ C1;
30 const uint64_t D4 = rotl<1>(C4) ^ C2;
31
32 const uint64_t B00 = A[ 0] ^ D1;
33 const uint64_t B01 = rotl<44>(A[ 6] ^ D2);
34 const uint64_t B02 = rotl<43>(A[12] ^ D3);
35 const uint64_t B03 = rotl<21>(A[18] ^ D4);
36 const uint64_t B04 = rotl<14>(A[24] ^ D0);
37 T[ 0] = B00 ^ (~B01 & B02) ^ RC;
38 T[ 1] = B01 ^ (~B02 & B03);
39 T[ 2] = B02 ^ (~B03 & B04);
40 T[ 3] = B03 ^ (~B04 & B00);
41 T[ 4] = B04 ^ (~B00 & B01);
42
43 const uint64_t B05 = rotl<28>(A[ 3] ^ D4);
44 const uint64_t B06 = rotl<20>(A[ 9] ^ D0);
45 const uint64_t B07 = rotl< 3>(A[10] ^ D1);
46 const uint64_t B08 = rotl<45>(A[16] ^ D2);
47 const uint64_t B09 = rotl<61>(A[22] ^ D3);
48 T[ 5] = B05 ^ (~B06 & B07);
49 T[ 6] = B06 ^ (~B07 & B08);
50 T[ 7] = B07 ^ (~B08 & B09);
51 T[ 8] = B08 ^ (~B09 & B05);
52 T[ 9] = B09 ^ (~B05 & B06);
53
54 const uint64_t B10 = rotl< 1>(A[ 1] ^ D2);
55 const uint64_t B11 = rotl< 6>(A[ 7] ^ D3);
56 const uint64_t B12 = rotl<25>(A[13] ^ D4);
57 const uint64_t B13 = rotl< 8>(A[19] ^ D0);
58 const uint64_t B14 = rotl<18>(A[20] ^ D1);
59 T[10] = B10 ^ (~B11 & B12);
60 T[11] = B11 ^ (~B12 & B13);
61 T[12] = B12 ^ (~B13 & B14);
62 T[13] = B13 ^ (~B14 & B10);
63 T[14] = B14 ^ (~B10 & B11);
64
65 const uint64_t B15 = rotl<27>(A[ 4] ^ D0);
66 const uint64_t B16 = rotl<36>(A[ 5] ^ D1);
67 const uint64_t B17 = rotl<10>(A[11] ^ D2);
68 const uint64_t B18 = rotl<15>(A[17] ^ D3);
69 const uint64_t B19 = rotl<56>(A[23] ^ D4);
70 T[15] = B15 ^ (~B16 & B17);
71 T[16] = B16 ^ (~B17 & B18);
72 T[17] = B17 ^ (~B18 & B19);
73 T[18] = B18 ^ (~B19 & B15);
74 T[19] = B19 ^ (~B15 & B16);
75
76 const uint64_t B20 = rotl<62>(A[ 2] ^ D3);
77 const uint64_t B21 = rotl<55>(A[ 8] ^ D4);
78 const uint64_t B22 = rotl<39>(A[14] ^ D0);
79 const uint64_t B23 = rotl<41>(A[15] ^ D1);
80 const uint64_t B24 = rotl< 2>(A[21] ^ D2);
81 T[20] = B20 ^ (~B21 & B22);
82 T[21] = B21 ^ (~B22 & B23);
83 T[22] = B22 ^ (~B23 & B24);
84 T[23] = B23 ^ (~B24 & B20);
85 T[24] = B24 ^ (~B20 & B21);
86 }
87
88 }
89
90 //static
91 void SHA_3::permute(uint64_t A[25])
92 {
93 #if defined(BOTAN_HAS_SHA3_BMI2)
94 if(CPUID::has_bmi2())
95 {
96 return permute_bmi2(A);
97 }
98 #endif
99
100 static const uint64_t RC[24] = {
101 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
102 0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
103 0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
104 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
105 0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
106 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
107 0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
108 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
109 };
110
111 uint64_t T[25];
112
113 for(size_t i = 0; i != 24; i += 2)
114 {
115 SHA3_round(T, A, RC[i+0]);
116 SHA3_round(A, T, RC[i+1]);
117 }
118 }
119
120 //static
121 size_t SHA_3::absorb(size_t bitrate,
122 secure_vector<uint64_t>& S, size_t S_pos,
123 const uint8_t input[], size_t length)
124 {
125 while(length > 0)
126 {
127 size_t to_take = std::min(length, bitrate / 8 - S_pos);
128
129 length -= to_take;
130
131 while(to_take && S_pos % 8)
132 {
133 S[S_pos / 8] ^= static_cast<uint64_t>(input[0]) << (8 * (S_pos % 8));
134
135 ++S_pos;
136 ++input;
137 --to_take;
138 }
139
140 while(to_take && to_take % 8 == 0)
141 {
142 S[S_pos / 8] ^= load_le<uint64_t>(input, 0);
143 S_pos += 8;
144 input += 8;
145 to_take -= 8;
146 }
147
148 while(to_take)
149 {
150 S[S_pos / 8] ^= static_cast<uint64_t>(input[0]) << (8 * (S_pos % 8));
151
152 ++S_pos;
153 ++input;
154 --to_take;
155 }
156
157 if(S_pos == bitrate / 8)
158 {
159 SHA_3::permute(S.data());
160 S_pos = 0;
161 }
162 }
163
164 return S_pos;
165 }
166
167 //static
168 void SHA_3::finish(size_t bitrate,
169 secure_vector<uint64_t>& S, size_t S_pos,
170 uint8_t init_pad, uint8_t fini_pad)
171 {
172 BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64");
173
174 S[S_pos / 8] ^= static_cast<uint64_t>(init_pad) << (8 * (S_pos % 8));
175 S[(bitrate / 64) - 1] ^= static_cast<uint64_t>(fini_pad) << 56;
176 SHA_3::permute(S.data());
177 }
178
179 //static
180 void SHA_3::expand(size_t bitrate,
181 secure_vector<uint64_t>& S,
182 uint8_t output[], size_t output_length)
183 {
184 BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64");
185
186 const size_t byterate = bitrate / 8;
187
188 while(output_length > 0)
189 {
190 const size_t copying = std::min(byterate, output_length);
191
192 copy_out_vec_le(output, copying, S);
193
194 output += copying;
195 output_length -= copying;
196
197 if(output_length > 0)
198 {
199 SHA_3::permute(S.data());
200 }
201 }
202 }
203
204 SHA_3::SHA_3(size_t output_bits) :
205 m_output_bits(output_bits),
206 m_bitrate(1600 - 2*output_bits),
207 m_S(25),
208 m_S_pos(0)
209 {
210 // We only support the parameters for SHA-3 in this constructor
211
212 if(output_bits != 224 && output_bits != 256 &&
213 output_bits != 384 && output_bits != 512)
214 throw Invalid_Argument("SHA_3: Invalid output length " +
215 std::to_string(output_bits));
216 }
217
218 std::string SHA_3::name() const
219 {
220 return "SHA-3(" + std::to_string(m_output_bits) + ")";
221 }
222
223 std::string SHA_3::provider() const
224 {
225 #if defined(BOTAN_HAS_SHA3_BMI2)
226 if(CPUID::has_bmi2())
227 {
228 return "bmi2";
229 }
230 #endif
231
232 return "base";
233 }
234
235 std::unique_ptr<HashFunction> SHA_3::copy_state() const
236 {
237 return std::unique_ptr<HashFunction>(new SHA_3(*this));
238 }
239
240 HashFunction* SHA_3::clone() const
241 {
242 return new SHA_3(m_output_bits);
243 }
244
245 void SHA_3::clear()
246 {
247 zeroise(m_S);
248 m_S_pos = 0;
249 }
250
251 void SHA_3::add_data(const uint8_t input[], size_t length)
252 {
253 m_S_pos = SHA_3::absorb(m_bitrate, m_S, m_S_pos, input, length);
254 }
255
256 void SHA_3::final_result(uint8_t output[])
257 {
258 SHA_3::finish(m_bitrate, m_S, m_S_pos, 0x06, 0x80);
259
260 /*
261 * We never have to run the permutation again because we only support
262 * limited output lengths
263 */
264 copy_out_vec_le(output, m_output_bits/8, m_S);
265
266 clear();
267 }
268
269 }
Botan::SHA_3::name
std::string name() const override
Definition: sha3.cpp:218
Botan::Invalid_Argument
Definition: exceptn.h:136
Botan::SHA_3::finish
static void finish(size_t bitrate, secure_vector< uint64_t > &S, size_t S_pos, uint8_t init_pad, uint8_t fini_pad)
Definition: sha3.cpp:168
Botan::SHA_3::expand
static void expand(size_t bitrate, secure_vector< uint64_t > &S, uint8_t output[], size_t output_length)
Definition: sha3.cpp:180
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
Botan::SHA_3::absorb
static size_t absorb(size_t bitrate, secure_vector< uint64_t > &S, size_t S_pos, const uint8_t input[], size_t length)
Definition: sha3.cpp:121
Botan::SHA_3::clone
HashFunction * clone() const override
Definition: sha3.cpp:240
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::load_le< uint64_t >
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:237
Botan
Definition: alg_id.cpp:13
BOTAN_ARG_CHECK
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:37
Botan::SHA_3::provider
std::string provider() const override
Definition: sha3.cpp:223
Botan::SHA_3::copy_state
std::unique_ptr< HashFunction > copy_state() const override
Definition: sha3.cpp:235
Botan::SHA_3::permute
static void permute(uint64_t A[25])
Definition: sha3.cpp:91
Botan::SHA_3::clear
void clear() override
Definition: sha3.cpp:245
Botan::HashFunction
Definition: hash.h:20
T
fe T
Definition: ge.cpp:37
Botan::SHA_3::SHA_3
SHA_3(size_t output_bits)
Definition: sha3.cpp:204
Botan::zeroise
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:160
Botan::copy_out_vec_le
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
Definition: loadstor.h:694