Botan  2.19.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/internal/sha3_round.h>
12 #include <botan/exceptn.h>
13 #include <botan/cpuid.h>
14 
15 namespace Botan {
16 
17 void SHA_3::permute(uint64_t A[25])
18  {
19 #if defined(BOTAN_HAS_SHA3_BMI2)
20  if(CPUID::has_bmi2())
21  {
22  return permute_bmi2(A);
23  }
24 #endif
25 
26  static const uint64_t RC[24] = {
27  0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
28  0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
29  0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
30  0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
31  0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
32  0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
33  0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
34  0x8000000000008080, 0x0000000080000001, 0x8000000080008008
35  };
36 
37  uint64_t T[25];
38 
39  for(size_t i = 0; i != 24; i += 2)
40  {
41  SHA3_round(T, A, RC[i+0]);
42  SHA3_round(A, T, RC[i+1]);
43  }
44  }
45 
46 //static
47 size_t SHA_3::absorb(size_t bitrate,
48  secure_vector<uint64_t>& S, size_t S_pos,
49  const uint8_t input[], size_t length)
50  {
51  while(length > 0)
52  {
53  size_t to_take = std::min(length, bitrate / 8 - S_pos);
54 
55  length -= to_take;
56 
57  while(to_take && S_pos % 8)
58  {
59  S[S_pos / 8] ^= static_cast<uint64_t>(input[0]) << (8 * (S_pos % 8));
60 
61  ++S_pos;
62  ++input;
63  --to_take;
64  }
65 
66  while(to_take && to_take % 8 == 0)
67  {
68  S[S_pos / 8] ^= load_le<uint64_t>(input, 0);
69  S_pos += 8;
70  input += 8;
71  to_take -= 8;
72  }
73 
74  while(to_take)
75  {
76  S[S_pos / 8] ^= static_cast<uint64_t>(input[0]) << (8 * (S_pos % 8));
77 
78  ++S_pos;
79  ++input;
80  --to_take;
81  }
82 
83  if(S_pos == bitrate / 8)
84  {
85  SHA_3::permute(S.data());
86  S_pos = 0;
87  }
88  }
89 
90  return S_pos;
91  }
92 
93 //static
94 void SHA_3::finish(size_t bitrate,
95  secure_vector<uint64_t>& S, size_t S_pos,
96  uint8_t init_pad, uint8_t fini_pad)
97  {
98  BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64");
99 
100  S[S_pos / 8] ^= static_cast<uint64_t>(init_pad) << (8 * (S_pos % 8));
101  S[(bitrate / 64) - 1] ^= static_cast<uint64_t>(fini_pad) << 56;
102  SHA_3::permute(S.data());
103  }
104 
105 //static
106 void SHA_3::expand(size_t bitrate,
108  uint8_t output[], size_t output_length)
109  {
110  BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64");
111 
112  const size_t byterate = bitrate / 8;
113 
114  while(output_length > 0)
115  {
116  const size_t copying = std::min(byterate, output_length);
117 
118  copy_out_vec_le(output, copying, S);
119 
120  output += copying;
121  output_length -= copying;
122 
123  if(output_length > 0)
124  {
125  SHA_3::permute(S.data());
126  }
127  }
128  }
129 
130 SHA_3::SHA_3(size_t output_bits) :
131  m_output_bits(output_bits),
132  m_bitrate(1600 - 2*output_bits),
133  m_S(25),
134  m_S_pos(0)
135  {
136  // We only support the parameters for SHA-3 in this constructor
137 
138  if(output_bits != 224 && output_bits != 256 &&
139  output_bits != 384 && output_bits != 512)
140  throw Invalid_Argument("SHA_3: Invalid output length " +
141  std::to_string(output_bits));
142  }
143 
144 std::string SHA_3::name() const
145  {
146  return "SHA-3(" + std::to_string(m_output_bits) + ")";
147  }
148 
149 std::string SHA_3::provider() const
150  {
151 #if defined(BOTAN_HAS_SHA3_BMI2)
152  if(CPUID::has_bmi2())
153  {
154  return "bmi2";
155  }
156 #endif
157 
158  return "base";
159  }
160 
161 std::unique_ptr<HashFunction> SHA_3::copy_state() const
162  {
163  return std::unique_ptr<HashFunction>(new SHA_3(*this));
164  }
165 
167  {
168  return new SHA_3(m_output_bits);
169  }
170 
172  {
173  zeroise(m_S);
174  m_S_pos = 0;
175  }
176 
177 void SHA_3::add_data(const uint8_t input[], size_t length)
178  {
179  m_S_pos = SHA_3::absorb(m_bitrate, m_S, m_S_pos, input, length);
180  }
181 
182 void SHA_3::final_result(uint8_t output[])
183  {
184  SHA_3::finish(m_bitrate, m_S, m_S_pos, 0x06, 0x80);
185 
186  /*
187  * We never have to run the permutation again because we only support
188  * limited output lengths
189  */
190  copy_out_vec_le(output, m_output_bits/8, m_S);
191 
192  clear();
193  }
194 
195 }
std::string name() const override
Definition: sha3.cpp:144
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:94
static void expand(size_t bitrate, secure_vector< uint64_t > &S, uint8_t output[], size_t output_length)
Definition: sha3.cpp:106
void BOTAN_FUNC_ISA("avx2") SHACAL2 SIMD_8x32 A
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:47
HashFunction * clone() const override
Definition: sha3.cpp:166
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
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:149
std::unique_ptr< HashFunction > copy_state() const override
Definition: sha3.cpp:161
static void permute(uint64_t A[25])
Definition: sha3.cpp:17
void clear() override
Definition: sha3.cpp:171
fe T
Definition: ge.cpp:37
SHA_3(size_t output_bits)
Definition: sha3.cpp:130
void SHA3_round(uint64_t T[25], const uint64_t A[25], uint64_t RC)
Definition: sha3_round.h:53
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:117
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
Definition: loadstor.h:694