Botan 3.4.0
Crypto and TLS for C&
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
Botan::SHA_1 Class Referencefinal

#include <sha1.h>

Inheritance diagram for Botan::SHA_1:
Botan::HashFunction Botan::Buffered_Computation

Public Types

using digest_type = secure_vector<uint32_t>
 

Public Member Functions

void clear () override
 
HashFunctionclone () const
 
std::unique_ptr< HashFunctioncopy_state () const override
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T final ()
 
void final (std::span< uint8_t > out)
 
template<concepts::resizable_byte_buffer T>
void final (T &out)
 
void final (uint8_t out[])
 
std::vector< uint8_t > final_stdvec ()
 
size_t hash_block_size () const override
 
std::string name () const override
 
std::unique_ptr< HashFunctionnew_object () const override
 
size_t output_length () const override
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T process (const uint8_t in[], size_t length)
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T process (std::span< const uint8_t > in)
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T process (std::string_view in)
 
std::string provider () const override
 
void update (const uint8_t in[], size_t length)
 
void update (std::span< const uint8_t > in)
 
void update (std::string_view str)
 
void update (uint8_t in)
 
void update_be (uint16_t val)
 
void update_be (uint32_t val)
 
void update_be (uint64_t val)
 
void update_le (uint16_t val)
 
void update_le (uint32_t val)
 
void update_le (uint64_t val)
 

Static Public Member Functions

static void compress_n (digest_type &digest, std::span< const uint8_t > input, size_t blocks)
 
static std::unique_ptr< HashFunctioncreate (std::string_view algo_spec, std::string_view provider="")
 
static std::unique_ptr< HashFunctioncreate_or_throw (std::string_view algo_spec, std::string_view provider="")
 
static void init (digest_type &digest)
 
static std::vector< std::string > providers (std::string_view algo_spec)
 
static void sha1_armv8_compress_n (digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
 
static void sha1_compress_x86 (digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
 
static void sse2_compress_n (digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
 

Static Public Attributes

static constexpr MD_Endian bit_endianness = MD_Endian::Big
 
static constexpr size_t block_bytes = 64
 
static constexpr MD_Endian byte_endianness = MD_Endian::Big
 
static constexpr size_t ctr_bytes = 8
 
static constexpr size_t output_bytes = 20
 

Detailed Description

NIST's SHA-1

Definition at line 18 of file sha1.h.

Member Typedef Documentation

◆ digest_type

Definition at line 20 of file sha1.h.

Member Function Documentation

◆ clear()

void Botan::SHA_1::clear ( )
inlineoverridevirtual

Reset the state.

Implements Botan::HashFunction.

Definition at line 44 of file sha1.h.

44{ m_md.clear(); }

◆ clone()

HashFunction * Botan::HashFunction::clone ( ) const
inlineinherited
Returns
new object representing the same algorithm as *this

Definition at line 87 of file hash.h.

87{ return this->new_object().release(); }
virtual std::unique_ptr< HashFunction > new_object() const =0

◆ compress_n()

void Botan::SHA_1::compress_n ( digest_type & digest,
std::span< const uint8_t > input,
size_t blocks )
static

Definition at line 63 of file sha1.cpp.

63 {
64 using namespace SHA1_F;
65
66#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
67 if(CPUID::has_intel_sha()) {
68 return sha1_compress_x86(digest, input, blocks);
69 }
70#endif
71
72#if defined(BOTAN_HAS_SHA1_ARMV8)
73 if(CPUID::has_arm_sha1()) {
74 return sha1_armv8_compress_n(digest, input, blocks);
75 }
76#endif
77
78#if defined(BOTAN_HAS_SHA1_SSE2)
79 if(CPUID::has_sse2()) {
80 return sse2_compress_n(digest, input, blocks);
81 }
82
83#endif
84
85 uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4];
86 std::array<uint32_t, 80> W;
87
88 BufferSlicer in(input);
89
90 for(size_t i = 0; i != blocks; ++i) {
91 load_be(W.data(), in.take(block_bytes).data(), 16);
92
93 for(size_t j = 16; j != 80; j += 8) {
94 W[j] = rotl<1>(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16]);
95 W[j + 1] = rotl<1>(W[j - 2] ^ W[j - 7] ^ W[j - 13] ^ W[j - 15]);
96 W[j + 2] = rotl<1>(W[j - 1] ^ W[j - 6] ^ W[j - 12] ^ W[j - 14]);
97 W[j + 3] = rotl<1>(W[j] ^ W[j - 5] ^ W[j - 11] ^ W[j - 13]);
98 W[j + 4] = rotl<1>(W[j + 1] ^ W[j - 4] ^ W[j - 10] ^ W[j - 12]);
99 W[j + 5] = rotl<1>(W[j + 2] ^ W[j - 3] ^ W[j - 9] ^ W[j - 11]);
100 W[j + 6] = rotl<1>(W[j + 3] ^ W[j - 2] ^ W[j - 8] ^ W[j - 10]);
101 W[j + 7] = rotl<1>(W[j + 4] ^ W[j - 1] ^ W[j - 7] ^ W[j - 9]);
102 }
103
104 F1(A, B, C, D, E, W[0]);
105 F1(E, A, B, C, D, W[1]);
106 F1(D, E, A, B, C, W[2]);
107 F1(C, D, E, A, B, W[3]);
108 F1(B, C, D, E, A, W[4]);
109 F1(A, B, C, D, E, W[5]);
110 F1(E, A, B, C, D, W[6]);
111 F1(D, E, A, B, C, W[7]);
112 F1(C, D, E, A, B, W[8]);
113 F1(B, C, D, E, A, W[9]);
114 F1(A, B, C, D, E, W[10]);
115 F1(E, A, B, C, D, W[11]);
116 F1(D, E, A, B, C, W[12]);
117 F1(C, D, E, A, B, W[13]);
118 F1(B, C, D, E, A, W[14]);
119 F1(A, B, C, D, E, W[15]);
120 F1(E, A, B, C, D, W[16]);
121 F1(D, E, A, B, C, W[17]);
122 F1(C, D, E, A, B, W[18]);
123 F1(B, C, D, E, A, W[19]);
124
125 F2(A, B, C, D, E, W[20]);
126 F2(E, A, B, C, D, W[21]);
127 F2(D, E, A, B, C, W[22]);
128 F2(C, D, E, A, B, W[23]);
129 F2(B, C, D, E, A, W[24]);
130 F2(A, B, C, D, E, W[25]);
131 F2(E, A, B, C, D, W[26]);
132 F2(D, E, A, B, C, W[27]);
133 F2(C, D, E, A, B, W[28]);
134 F2(B, C, D, E, A, W[29]);
135 F2(A, B, C, D, E, W[30]);
136 F2(E, A, B, C, D, W[31]);
137 F2(D, E, A, B, C, W[32]);
138 F2(C, D, E, A, B, W[33]);
139 F2(B, C, D, E, A, W[34]);
140 F2(A, B, C, D, E, W[35]);
141 F2(E, A, B, C, D, W[36]);
142 F2(D, E, A, B, C, W[37]);
143 F2(C, D, E, A, B, W[38]);
144 F2(B, C, D, E, A, W[39]);
145
146 F3(A, B, C, D, E, W[40]);
147 F3(E, A, B, C, D, W[41]);
148 F3(D, E, A, B, C, W[42]);
149 F3(C, D, E, A, B, W[43]);
150 F3(B, C, D, E, A, W[44]);
151 F3(A, B, C, D, E, W[45]);
152 F3(E, A, B, C, D, W[46]);
153 F3(D, E, A, B, C, W[47]);
154 F3(C, D, E, A, B, W[48]);
155 F3(B, C, D, E, A, W[49]);
156 F3(A, B, C, D, E, W[50]);
157 F3(E, A, B, C, D, W[51]);
158 F3(D, E, A, B, C, W[52]);
159 F3(C, D, E, A, B, W[53]);
160 F3(B, C, D, E, A, W[54]);
161 F3(A, B, C, D, E, W[55]);
162 F3(E, A, B, C, D, W[56]);
163 F3(D, E, A, B, C, W[57]);
164 F3(C, D, E, A, B, W[58]);
165 F3(B, C, D, E, A, W[59]);
166
167 F4(A, B, C, D, E, W[60]);
168 F4(E, A, B, C, D, W[61]);
169 F4(D, E, A, B, C, W[62]);
170 F4(C, D, E, A, B, W[63]);
171 F4(B, C, D, E, A, W[64]);
172 F4(A, B, C, D, E, W[65]);
173 F4(E, A, B, C, D, W[66]);
174 F4(D, E, A, B, C, W[67]);
175 F4(C, D, E, A, B, W[68]);
176 F4(B, C, D, E, A, W[69]);
177 F4(A, B, C, D, E, W[70]);
178 F4(E, A, B, C, D, W[71]);
179 F4(D, E, A, B, C, W[72]);
180 F4(C, D, E, A, B, W[73]);
181 F4(B, C, D, E, A, W[74]);
182 F4(A, B, C, D, E, W[75]);
183 F4(E, A, B, C, D, W[76]);
184 F4(D, E, A, B, C, W[77]);
185 F4(C, D, E, A, B, W[78]);
186 F4(B, C, D, E, A, W[79]);
187
188 A = (digest[0] += A);
189 B = (digest[1] += B);
190 C = (digest[2] += C);
191 D = (digest[3] += D);
192 E = (digest[4] += E);
193 }
194}
static void sha1_compress_x86(digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
Definition sha1_x86.cpp:21
static constexpr size_t block_bytes
Definition sha1.h:24
static void sse2_compress_n(digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
static void sha1_armv8_compress_n(digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:471

References block_bytes, Botan::load_be(), sha1_armv8_compress_n(), sha1_compress_x86(), sse2_compress_n(), and Botan::BufferSlicer::take().

◆ copy_state()

std::unique_ptr< HashFunction > Botan::SHA_1::copy_state ( ) const
overridevirtual

Return a new hash object with the same state as *this. This allows computing the hash of several messages with a common prefix more efficiently than would otherwise be possible.

This function should be called clone but that was already used for the case of returning an uninitialized object.

Returns
new hash object

Implements Botan::HashFunction.

Definition at line 229 of file sha1.cpp.

229 {
230 return std::make_unique<SHA_1>(*this);
231}

◆ create()

std::unique_ptr< HashFunction > Botan::HashFunction::create ( std::string_view algo_spec,
std::string_view provider = "" )
staticinherited

Create an instance based on a name, or return null if the algo/provider combination cannot be found. If provider is empty then best available is chosen.

Definition at line 107 of file hash.cpp.

107 {
108#if defined(BOTAN_HAS_COMMONCRYPTO)
109 if(provider.empty() || provider == "commoncrypto") {
110 if(auto hash = make_commoncrypto_hash(algo_spec))
111 return hash;
112
113 if(!provider.empty())
114 return nullptr;
115 }
116#endif
117
118 if(provider.empty() == false && provider != "base") {
119 return nullptr; // unknown provider
120 }
121
122#if defined(BOTAN_HAS_SHA1)
123 if(algo_spec == "SHA-1") {
124 return std::make_unique<SHA_1>();
125 }
126#endif
127
128#if defined(BOTAN_HAS_SHA2_32)
129 if(algo_spec == "SHA-224") {
130 return std::make_unique<SHA_224>();
131 }
132
133 if(algo_spec == "SHA-256") {
134 return std::make_unique<SHA_256>();
135 }
136#endif
137
138#if defined(BOTAN_HAS_SHA2_64)
139 if(algo_spec == "SHA-384") {
140 return std::make_unique<SHA_384>();
141 }
142
143 if(algo_spec == "SHA-512") {
144 return std::make_unique<SHA_512>();
145 }
146
147 if(algo_spec == "SHA-512-256") {
148 return std::make_unique<SHA_512_256>();
149 }
150#endif
151
152#if defined(BOTAN_HAS_RIPEMD_160)
153 if(algo_spec == "RIPEMD-160") {
154 return std::make_unique<RIPEMD_160>();
155 }
156#endif
157
158#if defined(BOTAN_HAS_WHIRLPOOL)
159 if(algo_spec == "Whirlpool") {
160 return std::make_unique<Whirlpool>();
161 }
162#endif
163
164#if defined(BOTAN_HAS_MD5)
165 if(algo_spec == "MD5") {
166 return std::make_unique<MD5>();
167 }
168#endif
169
170#if defined(BOTAN_HAS_MD4)
171 if(algo_spec == "MD4") {
172 return std::make_unique<MD4>();
173 }
174#endif
175
176#if defined(BOTAN_HAS_GOST_34_11)
177 if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") {
178 return std::make_unique<GOST_34_11>();
179 }
180#endif
181
182#if defined(BOTAN_HAS_ADLER32)
183 if(algo_spec == "Adler32") {
184 return std::make_unique<Adler32>();
185 }
186#endif
187
188#if defined(BOTAN_HAS_CRC24)
189 if(algo_spec == "CRC24") {
190 return std::make_unique<CRC24>();
191 }
192#endif
193
194#if defined(BOTAN_HAS_CRC32)
195 if(algo_spec == "CRC32") {
196 return std::make_unique<CRC32>();
197 }
198#endif
199
200#if defined(BOTAN_HAS_STREEBOG)
201 if(algo_spec == "Streebog-256") {
202 return std::make_unique<Streebog>(256);
203 }
204 if(algo_spec == "Streebog-512") {
205 return std::make_unique<Streebog>(512);
206 }
207#endif
208
209#if defined(BOTAN_HAS_SM3)
210 if(algo_spec == "SM3") {
211 return std::make_unique<SM3>();
212 }
213#endif
214
215 const SCAN_Name req(algo_spec);
216
217#if defined(BOTAN_HAS_SKEIN_512)
218 if(req.algo_name() == "Skein-512") {
219 return std::make_unique<Skein_512>(req.arg_as_integer(0, 512), req.arg(1, ""));
220 }
221#endif
222
223#if defined(BOTAN_HAS_BLAKE2B)
224 if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") {
225 return std::make_unique<BLAKE2b>(req.arg_as_integer(0, 512));
226 }
227#endif
228
229#if defined(BOTAN_HAS_BLAKE2S)
230 if(req.algo_name() == "Blake2s" || req.algo_name() == "BLAKE2s") {
231 return std::make_unique<BLAKE2s>(req.arg_as_integer(0, 256));
232 }
233#endif
234
235#if defined(BOTAN_HAS_KECCAK)
236 if(req.algo_name() == "Keccak-1600") {
237 return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
238 }
239#endif
240
241#if defined(BOTAN_HAS_SHA3)
242 if(req.algo_name() == "SHA-3") {
243 return std::make_unique<SHA_3>(req.arg_as_integer(0, 512));
244 }
245#endif
246
247#if defined(BOTAN_HAS_SHAKE)
248 if(req.algo_name() == "SHAKE-128" && req.arg_count() == 1) {
249 return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
250 }
251 if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1) {
252 return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
253 }
254#endif
255
256#if defined(BOTAN_HAS_PARALLEL_HASH)
257 if(req.algo_name() == "Parallel") {
258 std::vector<std::unique_ptr<HashFunction>> hashes;
259
260 for(size_t i = 0; i != req.arg_count(); ++i) {
261 auto h = HashFunction::create(req.arg(i));
262 if(!h) {
263 return nullptr;
264 }
265 hashes.push_back(std::move(h));
266 }
267
268 return std::make_unique<Parallel>(hashes);
269 }
270#endif
271
272#if defined(BOTAN_HAS_TRUNCATED_HASH)
273 if(req.algo_name() == "Truncated" && req.arg_count() == 2) {
274 auto hash = HashFunction::create(req.arg(0));
275 if(!hash) {
276 return nullptr;
277 }
278
279 return std::make_unique<Truncated_Hash>(std::move(hash), req.arg_as_integer(1));
280 }
281#endif
282
283#if defined(BOTAN_HAS_COMB4P)
284 if(req.algo_name() == "Comb4P" && req.arg_count() == 2) {
285 auto h1 = HashFunction::create(req.arg(0));
286 auto h2 = HashFunction::create(req.arg(1));
287
288 if(h1 && h2) {
289 return std::make_unique<Comb4P>(std::move(h1), std::move(h2));
290 }
291 }
292#endif
293
294 return nullptr;
295}
virtual std::string provider() const
Definition hash.h:49
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:107
std::unique_ptr< HashFunction > make_commoncrypto_hash(std::string_view name)

References Botan::SCAN_Name::algo_name(), Botan::SCAN_Name::arg(), Botan::SCAN_Name::arg_as_integer(), Botan::SCAN_Name::arg_count(), Botan::HashFunction::create(), Botan::make_commoncrypto_hash(), and Botan::HashFunction::provider().

Referenced by botan_hash_init(), Botan::EME::create(), Botan::EMSA::create(), Botan::BlockCipher::create(), Botan::HashFunction::create(), Botan::KDF::create(), Botan::MessageAuthenticationCode::create(), Botan::PBKDF::create(), Botan::PasswordHashFamily::create(), Botan::HashFunction::create_or_throw(), Botan::Certificate_Store_In_Memory::find_cert_by_pubkey_sha1(), Botan::Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256(), and Botan::X942_PRF::kdf().

◆ create_or_throw()

std::unique_ptr< HashFunction > Botan::HashFunction::create_or_throw ( std::string_view algo_spec,
std::string_view provider = "" )
staticinherited

◆ final() [1/4]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::Buffered_Computation::final ( )
inlineinherited

Complete the computation and retrieve the final result as a container of your choice.

Returns
a contiguous container holding the result

Definition at line 78 of file buf_comp.h.

78 {
79 T output(output_length());
80 final_result(output);
81 return output;
82 }
virtual size_t output_length() const =0
FE_25519 T
Definition ge.cpp:34

References T.

◆ final() [2/4]

void Botan::Buffered_Computation::final ( std::span< uint8_t > out)
inlineinherited

Definition at line 86 of file buf_comp.h.

86 {
87 BOTAN_ARG_CHECK(out.size() >= output_length(), "provided output buffer has insufficient capacity");
88 final_result(out);
89 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29

References BOTAN_ARG_CHECK.

◆ final() [3/4]

template<concepts::resizable_byte_buffer T>
void Botan::Buffered_Computation::final ( T & out)
inlineinherited

Definition at line 92 of file buf_comp.h.

92 {
93 out.resize(output_length());
94 final_result(out);
95 }

◆ final() [4/4]

void Botan::Buffered_Computation::final ( uint8_t out[])
inlineinherited

◆ final_stdvec()

std::vector< uint8_t > Botan::Buffered_Computation::final_stdvec ( )
inlineinherited

Definition at line 84 of file buf_comp.h.

84{ return final<std::vector<uint8_t>>(); }

◆ hash_block_size()

size_t Botan::SHA_1::hash_block_size ( ) const
inlineoverridevirtual
Returns
hash block size as defined for this algorithm

Reimplemented from Botan::HashFunction.

Definition at line 36 of file sha1.h.

36{ return block_bytes; }

References block_bytes.

◆ init()

void Botan::SHA_1::init ( digest_type & digest)
static

Definition at line 199 of file sha1.cpp.

199 {
200 digest.assign({0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0});
201}

◆ name()

std::string Botan::SHA_1::name ( ) const
inlineoverridevirtual
Returns
the hash function name

Implements Botan::HashFunction.

Definition at line 32 of file sha1.h.

32{ return "SHA-1"; }

◆ new_object()

std::unique_ptr< HashFunction > Botan::SHA_1::new_object ( ) const
overridevirtual
Returns
new object representing the same algorithm as *this

Implements Botan::HashFunction.

Definition at line 225 of file sha1.cpp.

225 {
226 return std::make_unique<SHA_1>();
227}

◆ output_length()

size_t Botan::SHA_1::output_length ( ) const
inlineoverridevirtual
Returns
length of the output of this function in bytes

Implements Botan::Buffered_Computation.

Definition at line 34 of file sha1.h.

34{ return 20; }

◆ process() [1/3]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::Buffered_Computation::process ( const uint8_t in[],
size_t length )
inlineinherited

Update and finalize computation. Does the same as calling update() and final() consecutively.

Parameters
inthe input to process as a byte array
lengththe length of the byte array
Returns
the result of the call to final()

Definition at line 105 of file buf_comp.h.

105 {
106 update(in, length);
107 return final<T>();
108 }
int(* update)(CTX *, const void *, CC_LONG len)

References update.

Referenced by Botan::Dilithium_Symmetric_Primitives::CRH(), and Botan::Dilithium_Symmetric_Primitives::H().

◆ process() [2/3]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::Buffered_Computation::process ( std::span< const uint8_t > in)
inlineinherited

Update and finalize computation. Does the same as calling update() and final() consecutively.

Parameters
inthe input to process as a contiguous container
Returns
the result of the call to final()

Definition at line 129 of file buf_comp.h.

129 {
130 update(in);
131 return final<T>();
132 }

References update.

◆ process() [3/3]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::Buffered_Computation::process ( std::string_view in)
inlineinherited

Update and finalize computation. Does the same as calling update() and final() consecutively.

Parameters
inthe input to process as a string
Returns
the result of the call to final()

Definition at line 117 of file buf_comp.h.

117 {
118 update(in);
119 return final<T>();
120 }

References update.

◆ provider()

std::string Botan::SHA_1::provider ( ) const
overridevirtual
Returns
provider information about this implementation. Default is "base", might also return "sse2", "avx2", "openssl", or some other arbitrary string.

Reimplemented from Botan::HashFunction.

Definition at line 203 of file sha1.cpp.

203 {
204#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
205 if(CPUID::has_intel_sha()) {
206 return "intel_sha";
207 }
208#endif
209
210#if defined(BOTAN_HAS_SHA1_ARMV8)
211 if(CPUID::has_arm_sha1()) {
212 return "armv8_sha";
213 }
214#endif
215
216#if defined(BOTAN_HAS_SHA1_SSE2)
217 if(CPUID::has_sse2()) {
218 return "sse2";
219 }
220#endif
221
222 return "base";
223}

◆ providers()

std::vector< std::string > Botan::HashFunction::providers ( std::string_view algo_spec)
staticinherited
Returns
list of available providers for this algorithm, empty if not available
Parameters
algo_specalgorithm name

Definition at line 305 of file hash.cpp.

305 {
306 return probe_providers_of<HashFunction>(algo_spec, {"base", "commoncrypto"});
307}

◆ sha1_armv8_compress_n()

void Botan::SHA_1::sha1_armv8_compress_n ( digest_type & digest,
std::span< const uint8_t > blocks,
size_t block_count )
static

Definition at line 20 of file sha1_armv8.cpp.

20 {
21 uint32x4_t ABCD;
22 uint32_t E0;
23
24 // Load magic constants
25 const uint32x4_t C0 = vdupq_n_u32(0x5A827999);
26 const uint32x4_t C1 = vdupq_n_u32(0x6ED9EBA1);
27 const uint32x4_t C2 = vdupq_n_u32(0x8F1BBCDC);
28 const uint32x4_t C3 = vdupq_n_u32(0xCA62C1D6);
29
30 ABCD = vld1q_u32(&digest[0]);
31 E0 = digest[4];
32
33 // Intermediate void* cast due to https://llvm.org/bugs/show_bug.cgi?id=20670
34 const uint32_t* input32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const void*>(input8.data()));
35
36 while(blocks) {
37 // Save current hash
38 const uint32x4_t ABCD_SAVED = ABCD;
39 const uint32_t E0_SAVED = E0;
40
41 uint32x4_t MSG0, MSG1, MSG2, MSG3;
42 uint32x4_t TMP0, TMP1;
43 uint32_t E1;
44
45 MSG0 = vld1q_u32(input32 + 0);
46 MSG1 = vld1q_u32(input32 + 4);
47 MSG2 = vld1q_u32(input32 + 8);
48 MSG3 = vld1q_u32(input32 + 12);
49
50 MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0)));
51 MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1)));
52 MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2)));
53 MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3)));
54
55 TMP0 = vaddq_u32(MSG0, C0);
56 TMP1 = vaddq_u32(MSG1, C0);
57
58 // Rounds 0-3
59 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
60 ABCD = vsha1cq_u32(ABCD, E0, TMP0);
61 TMP0 = vaddq_u32(MSG2, C0);
62 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
63
64 // Rounds 4-7
65 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
66 ABCD = vsha1cq_u32(ABCD, E1, TMP1);
67 TMP1 = vaddq_u32(MSG3, C0);
68 MSG0 = vsha1su1q_u32(MSG0, MSG3);
69 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
70
71 // Rounds 8-11
72 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
73 ABCD = vsha1cq_u32(ABCD, E0, TMP0);
74 TMP0 = vaddq_u32(MSG0, C0);
75 MSG1 = vsha1su1q_u32(MSG1, MSG0);
76 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
77
78 // Rounds 12-15
79 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
80 ABCD = vsha1cq_u32(ABCD, E1, TMP1);
81 TMP1 = vaddq_u32(MSG1, C1);
82 MSG2 = vsha1su1q_u32(MSG2, MSG1);
83 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
84
85 // Rounds 16-19
86 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
87 ABCD = vsha1cq_u32(ABCD, E0, TMP0);
88 TMP0 = vaddq_u32(MSG2, C1);
89 MSG3 = vsha1su1q_u32(MSG3, MSG2);
90 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
91
92 // Rounds 20-23
93 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
94 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
95 TMP1 = vaddq_u32(MSG3, C1);
96 MSG0 = vsha1su1q_u32(MSG0, MSG3);
97 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
98
99 // Rounds 24-27
100 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
101 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
102 TMP0 = vaddq_u32(MSG0, C1);
103 MSG1 = vsha1su1q_u32(MSG1, MSG0);
104 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
105
106 // Rounds 28-31
107 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
108 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
109 TMP1 = vaddq_u32(MSG1, C1);
110 MSG2 = vsha1su1q_u32(MSG2, MSG1);
111 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
112
113 // Rounds 32-35
114 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
115 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
116 TMP0 = vaddq_u32(MSG2, C2);
117 MSG3 = vsha1su1q_u32(MSG3, MSG2);
118 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
119
120 // Rounds 36-39
121 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
122 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
123 TMP1 = vaddq_u32(MSG3, C2);
124 MSG0 = vsha1su1q_u32(MSG0, MSG3);
125 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
126
127 // Rounds 40-43
128 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
129 ABCD = vsha1mq_u32(ABCD, E0, TMP0);
130 TMP0 = vaddq_u32(MSG0, C2);
131 MSG1 = vsha1su1q_u32(MSG1, MSG0);
132 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
133
134 // Rounds 44-47
135 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
136 ABCD = vsha1mq_u32(ABCD, E1, TMP1);
137 TMP1 = vaddq_u32(MSG1, C2);
138 MSG2 = vsha1su1q_u32(MSG2, MSG1);
139 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
140
141 // Rounds 48-51
142 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
143 ABCD = vsha1mq_u32(ABCD, E0, TMP0);
144 TMP0 = vaddq_u32(MSG2, C2);
145 MSG3 = vsha1su1q_u32(MSG3, MSG2);
146 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
147
148 // Rounds 52-55
149 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
150 ABCD = vsha1mq_u32(ABCD, E1, TMP1);
151 TMP1 = vaddq_u32(MSG3, C3);
152 MSG0 = vsha1su1q_u32(MSG0, MSG3);
153 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
154
155 // Rounds 56-59
156 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
157 ABCD = vsha1mq_u32(ABCD, E0, TMP0);
158 TMP0 = vaddq_u32(MSG0, C3);
159 MSG1 = vsha1su1q_u32(MSG1, MSG0);
160 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
161
162 // Rounds 60-63
163 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
164 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
165 TMP1 = vaddq_u32(MSG1, C3);
166 MSG2 = vsha1su1q_u32(MSG2, MSG1);
167 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
168
169 // Rounds 64-67
170 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
171 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
172 TMP0 = vaddq_u32(MSG2, C3);
173 MSG3 = vsha1su1q_u32(MSG3, MSG2);
174 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
175
176 // Rounds 68-71
177 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
178 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
179 TMP1 = vaddq_u32(MSG3, C3);
180 MSG0 = vsha1su1q_u32(MSG0, MSG3);
181
182 // Rounds 72-75
183 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
184 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
185
186 // Rounds 76-79
187 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
188 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
189
190 // Add state back
191 E0 += E0_SAVED;
192 ABCD = vaddq_u32(ABCD_SAVED, ABCD);
193
194 input32 += 64 / 4;
195 blocks--;
196 }
197
198 // Save digest
199 vst1q_u32(&digest[0], ABCD);
200 digest[4] = E0;
201}

Referenced by compress_n().

◆ sha1_compress_x86()

void Botan::SHA_1::sha1_compress_x86 ( digest_type & digest,
std::span< const uint8_t > blocks,
size_t block_count )
static

Definition at line 21 of file sha1_x86.cpp.

21 {
22 const __m128i MASK = _mm_set_epi64x(0x0001020304050607, 0x08090a0b0c0d0e0f);
23 const __m128i* input_mm = reinterpret_cast<const __m128i*>(input.data());
24
25 uint32_t* state = digest.data();
26
27 // Load initial values
28 __m128i ABCD = _mm_loadu_si128(reinterpret_cast<__m128i*>(state));
29 __m128i E0 = _mm_set_epi32(state[4], 0, 0, 0);
30 ABCD = _mm_shuffle_epi32(ABCD, 0x1B);
31
32 while(blocks) {
33 // Save current hash
34 const __m128i ABCD_SAVE = ABCD;
35 const __m128i E0_SAVE = E0;
36
37 __m128i MSG0, MSG1, MSG2, MSG3;
38 __m128i E1;
39
40 // Rounds 0-3
41 MSG0 = _mm_loadu_si128(input_mm + 0);
42 MSG0 = _mm_shuffle_epi8(MSG0, MASK);
43 E0 = _mm_add_epi32(E0, MSG0);
44 E1 = ABCD;
45 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
46
47 // Rounds 4-7
48 MSG1 = _mm_loadu_si128(input_mm + 1);
49 MSG1 = _mm_shuffle_epi8(MSG1, MASK);
50 E1 = _mm_sha1nexte_epu32(E1, MSG1);
51 E0 = ABCD;
52 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0);
53 MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
54
55 // Rounds 8-11
56 MSG2 = _mm_loadu_si128(input_mm + 2);
57 MSG2 = _mm_shuffle_epi8(MSG2, MASK);
58 E0 = _mm_sha1nexte_epu32(E0, MSG2);
59 E1 = ABCD;
60 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
61 MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
62 MSG0 = _mm_xor_si128(MSG0, MSG2);
63
64 // Rounds 12-15
65 MSG3 = _mm_loadu_si128(input_mm + 3);
66 MSG3 = _mm_shuffle_epi8(MSG3, MASK);
67 E1 = _mm_sha1nexte_epu32(E1, MSG3);
68 E0 = ABCD;
69 MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
70 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0);
71 MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
72 MSG1 = _mm_xor_si128(MSG1, MSG3);
73
74 // Rounds 16-19
75 E0 = _mm_sha1nexte_epu32(E0, MSG0);
76 E1 = ABCD;
77 MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
78 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
79 MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
80 MSG2 = _mm_xor_si128(MSG2, MSG0);
81
82 // Rounds 20-23
83 E1 = _mm_sha1nexte_epu32(E1, MSG1);
84 E0 = ABCD;
85 MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
86 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
87 MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
88 MSG3 = _mm_xor_si128(MSG3, MSG1);
89
90 // Rounds 24-27
91 E0 = _mm_sha1nexte_epu32(E0, MSG2);
92 E1 = ABCD;
93 MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
94 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1);
95 MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
96 MSG0 = _mm_xor_si128(MSG0, MSG2);
97
98 // Rounds 28-31
99 E1 = _mm_sha1nexte_epu32(E1, MSG3);
100 E0 = ABCD;
101 MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
102 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
103 MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
104 MSG1 = _mm_xor_si128(MSG1, MSG3);
105
106 // Rounds 32-35
107 E0 = _mm_sha1nexte_epu32(E0, MSG0);
108 E1 = ABCD;
109 MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
110 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1);
111 MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
112 MSG2 = _mm_xor_si128(MSG2, MSG0);
113
114 // Rounds 36-39
115 E1 = _mm_sha1nexte_epu32(E1, MSG1);
116 E0 = ABCD;
117 MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
118 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
119 MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
120 MSG3 = _mm_xor_si128(MSG3, MSG1);
121
122 // Rounds 40-43
123 E0 = _mm_sha1nexte_epu32(E0, MSG2);
124 E1 = ABCD;
125 MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
126 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
127 MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
128 MSG0 = _mm_xor_si128(MSG0, MSG2);
129
130 // Rounds 44-47
131 E1 = _mm_sha1nexte_epu32(E1, MSG3);
132 E0 = ABCD;
133 MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
134 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2);
135 MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
136 MSG1 = _mm_xor_si128(MSG1, MSG3);
137
138 // Rounds 48-51
139 E0 = _mm_sha1nexte_epu32(E0, MSG0);
140 E1 = ABCD;
141 MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
142 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
143 MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
144 MSG2 = _mm_xor_si128(MSG2, MSG0);
145
146 // Rounds 52-55
147 E1 = _mm_sha1nexte_epu32(E1, MSG1);
148 E0 = ABCD;
149 MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
150 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2);
151 MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
152 MSG3 = _mm_xor_si128(MSG3, MSG1);
153
154 // Rounds 56-59
155 E0 = _mm_sha1nexte_epu32(E0, MSG2);
156 E1 = ABCD;
157 MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
158 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
159 MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
160 MSG0 = _mm_xor_si128(MSG0, MSG2);
161
162 // Rounds 60-63
163 E1 = _mm_sha1nexte_epu32(E1, MSG3);
164 E0 = ABCD;
165 MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
166 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
167 MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
168 MSG1 = _mm_xor_si128(MSG1, MSG3);
169
170 // Rounds 64-67
171 E0 = _mm_sha1nexte_epu32(E0, MSG0);
172 E1 = ABCD;
173 MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
174 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3);
175 MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
176 MSG2 = _mm_xor_si128(MSG2, MSG0);
177
178 // Rounds 68-71
179 E1 = _mm_sha1nexte_epu32(E1, MSG1);
180 E0 = ABCD;
181 MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
182 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
183 MSG3 = _mm_xor_si128(MSG3, MSG1);
184
185 // Rounds 72-75
186 E0 = _mm_sha1nexte_epu32(E0, MSG2);
187 E1 = ABCD;
188 MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
189 ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3);
190
191 // Rounds 76-79
192 E1 = _mm_sha1nexte_epu32(E1, MSG3);
193 E0 = ABCD;
194 ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
195
196 // Add values back to state
197 E0 = _mm_sha1nexte_epu32(E0, E0_SAVE);
198 ABCD = _mm_add_epi32(ABCD, ABCD_SAVE);
199
200 input_mm += 4;
201 blocks--;
202 }
203
204 // Save state
205 ABCD = _mm_shuffle_epi32(ABCD, 0x1B);
206 _mm_storeu_si128(reinterpret_cast<__m128i*>(state), ABCD);
207 state[4] = _mm_extract_epi32(E0, 3);
208}

Referenced by compress_n().

◆ sse2_compress_n()

static void Botan::SHA_1::sse2_compress_n ( digest_type & digest,
std::span< const uint8_t > blocks,
size_t block_count )
static

Referenced by compress_n().

◆ update() [1/4]

void Botan::Buffered_Computation::update ( const uint8_t in[],
size_t length )
inlineinherited

◆ update() [2/4]

void Botan::Buffered_Computation::update ( std::span< const uint8_t > in)
inlineinherited

Add new input to process.

Parameters
inthe input to process as a contiguous data range

Definition at line 41 of file buf_comp.h.

41{ add_data(in); }

◆ update() [3/4]

void Botan::Buffered_Computation::update ( std::string_view str)
inlineinherited

Add new input to process.

Parameters
strthe input to process as a std::string_view. Will be interpreted as a byte array based on the strings encoding.

Definition at line 56 of file buf_comp.h.

56{ add_data({cast_char_ptr_to_uint8(str.data()), str.size()}); }
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition mem_ops.h:275

References Botan::cast_char_ptr_to_uint8().

◆ update() [4/4]

void Botan::Buffered_Computation::update ( uint8_t in)
inlineinherited

Process a single byte.

Parameters
inthe byte to process

Definition at line 62 of file buf_comp.h.

62{ add_data({&in, 1}); }

◆ update_be() [1/3]

void Botan::Buffered_Computation::update_be ( uint16_t val)
inherited

Definition at line 13 of file buf_comp.cpp.

13 {
14 uint8_t inb[sizeof(val)];
15 store_be(val, inb);
16 add_data({inb, sizeof(inb)});
17}
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:711

References Botan::store_be().

Referenced by Botan::mgf1_mask(), and Botan::pbkdf2().

◆ update_be() [2/3]

void Botan::Buffered_Computation::update_be ( uint32_t val)
inherited

Definition at line 19 of file buf_comp.cpp.

19 {
20 uint8_t inb[sizeof(val)];
21 store_be(val, inb);
22 add_data({inb, sizeof(inb)});
23}

References Botan::store_be().

◆ update_be() [3/3]

void Botan::Buffered_Computation::update_be ( uint64_t val)
inherited

Definition at line 25 of file buf_comp.cpp.

25 {
26 uint8_t inb[sizeof(val)];
27 store_be(val, inb);
28 add_data({inb, sizeof(inb)});
29}

References Botan::store_be().

◆ update_le() [1/3]

void Botan::Buffered_Computation::update_le ( uint16_t val)
inherited

Definition at line 31 of file buf_comp.cpp.

31 {
32 uint8_t inb[sizeof(val)];
33 store_le(val, inb);
34 add_data({inb, sizeof(inb)});
35}
constexpr auto store_le(ParamTs &&... params)
Definition loadstor.h:702

References Botan::store_le().

◆ update_le() [2/3]

void Botan::Buffered_Computation::update_le ( uint32_t val)
inherited

Definition at line 37 of file buf_comp.cpp.

37 {
38 uint8_t inb[sizeof(val)];
39 store_le(val, inb);
40 add_data({inb, sizeof(inb)});
41}

References Botan::store_le().

◆ update_le() [3/3]

void Botan::Buffered_Computation::update_le ( uint64_t val)
inherited

Definition at line 43 of file buf_comp.cpp.

43 {
44 uint8_t inb[sizeof(val)];
45 store_le(val, inb);
46 add_data({inb, sizeof(inb)});
47}

References Botan::store_le().

Member Data Documentation

◆ bit_endianness

constexpr MD_Endian Botan::SHA_1::bit_endianness = MD_Endian::Big
staticconstexpr

Definition at line 23 of file sha1.h.

◆ block_bytes

constexpr size_t Botan::SHA_1::block_bytes = 64
staticconstexpr

Definition at line 24 of file sha1.h.

Referenced by compress_n(), and hash_block_size().

◆ byte_endianness

constexpr MD_Endian Botan::SHA_1::byte_endianness = MD_Endian::Big
staticconstexpr

Definition at line 22 of file sha1.h.

◆ ctr_bytes

constexpr size_t Botan::SHA_1::ctr_bytes = 8
staticconstexpr

Definition at line 26 of file sha1.h.

◆ output_bytes

constexpr size_t Botan::SHA_1::output_bytes = 20
staticconstexpr

Definition at line 25 of file sha1.h.


The documentation for this class was generated from the following files: