Botan  2.12.1
Crypto and TLS for C++11
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,
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 
241  {
242  return new SHA_3(m_output_bits);
243  }
244 
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 }
std::string name() const override
Definition: sha3.cpp:218
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
static void expand(size_t bitrate, secure_vector< uint64_t > &S, uint8_t output[], size_t output_length)
Definition: sha3.cpp:180
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
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
HashFunction * clone() const override
Definition: sha3.cpp:240
size_t output_length() const override
Definition: sha3.h:33
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:237
Definition: alg_id.cpp:13
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:37
std::string provider() const override
Definition: sha3.cpp:223
std::unique_ptr< HashFunction > copy_state() const override
Definition: sha3.cpp:235
static void permute(uint64_t A[25])
Definition: sha3.cpp:91
void clear() override
Definition: sha3.cpp:245
fe T
Definition: ge.cpp:37
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
SHA_3(size_t output_bits)
Definition: sha3.cpp:204
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:160
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
Definition: loadstor.h:694