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