Botan 2.19.3
Crypto and TLS for C&
sha160.cpp
Go to the documentation of this file.
1/*
2* SHA-160
3* (C) 1999-2008,2011 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/sha160.h>
9#include <botan/loadstor.h>
10#include <botan/rotate.h>
11#include <botan/cpuid.h>
12
13namespace Botan {
14
15std::unique_ptr<HashFunction> SHA_160::copy_state() const
16 {
17 return std::unique_ptr<HashFunction>(new SHA_160(*this));
18 }
19
20namespace SHA1_F {
21
22namespace {
23
24/*
25* SHA-160 F1 Function
26*/
27inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
28 {
29 E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotl<5>(A);
30 B = rotl<30>(B);
31 }
32
33/*
34* SHA-160 F2 Function
35*/
36inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
37 {
38 E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotl<5>(A);
39 B = rotl<30>(B);
40 }
41
42/*
43* SHA-160 F3 Function
44*/
45inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
46 {
47 E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotl<5>(A);
48 B = rotl<30>(B);
49 }
50
51/*
52* SHA-160 F4 Function
53*/
54inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
55 {
56 E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotl<5>(A);
57 B = rotl<30>(B);
58 }
59
60}
61
62}
63
64/*
65* SHA-160 Compression Function
66*/
67void SHA_160::compress_n(const uint8_t input[], size_t blocks)
68 {
69 using namespace SHA1_F;
70
71#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
72 if(CPUID::has_intel_sha())
73 {
74 return sha1_compress_x86(m_digest, input, blocks);
75 }
76#endif
77
78#if defined(BOTAN_HAS_SHA1_ARMV8)
79 if(CPUID::has_arm_sha1())
80 {
81 return sha1_armv8_compress_n(m_digest, input, blocks);
82 }
83#endif
84
85#if defined(BOTAN_HAS_SHA1_SSE2)
86 if(CPUID::has_sse2())
87 {
88 return sse2_compress_n(m_digest, input, blocks);
89 }
90
91#endif
92
93 uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2],
94 D = m_digest[3], E = m_digest[4];
95
96 m_W.resize(80);
97
98 for(size_t i = 0; i != blocks; ++i)
99 {
100 load_be(m_W.data(), input, 16);
101
102 for(size_t j = 16; j != 80; j += 8)
103 {
104 m_W[j ] = rotl<1>(m_W[j-3] ^ m_W[j-8] ^ m_W[j-14] ^ m_W[j-16]);
105 m_W[j+1] = rotl<1>(m_W[j-2] ^ m_W[j-7] ^ m_W[j-13] ^ m_W[j-15]);
106 m_W[j+2] = rotl<1>(m_W[j-1] ^ m_W[j-6] ^ m_W[j-12] ^ m_W[j-14]);
107 m_W[j+3] = rotl<1>(m_W[j ] ^ m_W[j-5] ^ m_W[j-11] ^ m_W[j-13]);
108 m_W[j+4] = rotl<1>(m_W[j+1] ^ m_W[j-4] ^ m_W[j-10] ^ m_W[j-12]);
109 m_W[j+5] = rotl<1>(m_W[j+2] ^ m_W[j-3] ^ m_W[j- 9] ^ m_W[j-11]);
110 m_W[j+6] = rotl<1>(m_W[j+3] ^ m_W[j-2] ^ m_W[j- 8] ^ m_W[j-10]);
111 m_W[j+7] = rotl<1>(m_W[j+4] ^ m_W[j-1] ^ m_W[j- 7] ^ m_W[j- 9]);
112 }
113
114 F1(A, B, C, D, E, m_W[ 0]); F1(E, A, B, C, D, m_W[ 1]);
115 F1(D, E, A, B, C, m_W[ 2]); F1(C, D, E, A, B, m_W[ 3]);
116 F1(B, C, D, E, A, m_W[ 4]); F1(A, B, C, D, E, m_W[ 5]);
117 F1(E, A, B, C, D, m_W[ 6]); F1(D, E, A, B, C, m_W[ 7]);
118 F1(C, D, E, A, B, m_W[ 8]); F1(B, C, D, E, A, m_W[ 9]);
119 F1(A, B, C, D, E, m_W[10]); F1(E, A, B, C, D, m_W[11]);
120 F1(D, E, A, B, C, m_W[12]); F1(C, D, E, A, B, m_W[13]);
121 F1(B, C, D, E, A, m_W[14]); F1(A, B, C, D, E, m_W[15]);
122 F1(E, A, B, C, D, m_W[16]); F1(D, E, A, B, C, m_W[17]);
123 F1(C, D, E, A, B, m_W[18]); F1(B, C, D, E, A, m_W[19]);
124
125 F2(A, B, C, D, E, m_W[20]); F2(E, A, B, C, D, m_W[21]);
126 F2(D, E, A, B, C, m_W[22]); F2(C, D, E, A, B, m_W[23]);
127 F2(B, C, D, E, A, m_W[24]); F2(A, B, C, D, E, m_W[25]);
128 F2(E, A, B, C, D, m_W[26]); F2(D, E, A, B, C, m_W[27]);
129 F2(C, D, E, A, B, m_W[28]); F2(B, C, D, E, A, m_W[29]);
130 F2(A, B, C, D, E, m_W[30]); F2(E, A, B, C, D, m_W[31]);
131 F2(D, E, A, B, C, m_W[32]); F2(C, D, E, A, B, m_W[33]);
132 F2(B, C, D, E, A, m_W[34]); F2(A, B, C, D, E, m_W[35]);
133 F2(E, A, B, C, D, m_W[36]); F2(D, E, A, B, C, m_W[37]);
134 F2(C, D, E, A, B, m_W[38]); F2(B, C, D, E, A, m_W[39]);
135
136 F3(A, B, C, D, E, m_W[40]); F3(E, A, B, C, D, m_W[41]);
137 F3(D, E, A, B, C, m_W[42]); F3(C, D, E, A, B, m_W[43]);
138 F3(B, C, D, E, A, m_W[44]); F3(A, B, C, D, E, m_W[45]);
139 F3(E, A, B, C, D, m_W[46]); F3(D, E, A, B, C, m_W[47]);
140 F3(C, D, E, A, B, m_W[48]); F3(B, C, D, E, A, m_W[49]);
141 F3(A, B, C, D, E, m_W[50]); F3(E, A, B, C, D, m_W[51]);
142 F3(D, E, A, B, C, m_W[52]); F3(C, D, E, A, B, m_W[53]);
143 F3(B, C, D, E, A, m_W[54]); F3(A, B, C, D, E, m_W[55]);
144 F3(E, A, B, C, D, m_W[56]); F3(D, E, A, B, C, m_W[57]);
145 F3(C, D, E, A, B, m_W[58]); F3(B, C, D, E, A, m_W[59]);
146
147 F4(A, B, C, D, E, m_W[60]); F4(E, A, B, C, D, m_W[61]);
148 F4(D, E, A, B, C, m_W[62]); F4(C, D, E, A, B, m_W[63]);
149 F4(B, C, D, E, A, m_W[64]); F4(A, B, C, D, E, m_W[65]);
150 F4(E, A, B, C, D, m_W[66]); F4(D, E, A, B, C, m_W[67]);
151 F4(C, D, E, A, B, m_W[68]); F4(B, C, D, E, A, m_W[69]);
152 F4(A, B, C, D, E, m_W[70]); F4(E, A, B, C, D, m_W[71]);
153 F4(D, E, A, B, C, m_W[72]); F4(C, D, E, A, B, m_W[73]);
154 F4(B, C, D, E, A, m_W[74]); F4(A, B, C, D, E, m_W[75]);
155 F4(E, A, B, C, D, m_W[76]); F4(D, E, A, B, C, m_W[77]);
156 F4(C, D, E, A, B, m_W[78]); F4(B, C, D, E, A, m_W[79]);
157
158 A = (m_digest[0] += A);
159 B = (m_digest[1] += B);
160 C = (m_digest[2] += C);
161 D = (m_digest[3] += D);
162 E = (m_digest[4] += E);
163
164 input += hash_block_size();
165 }
166 }
167
168/*
169* Copy out the digest
170*/
171void SHA_160::copy_out(uint8_t output[])
172 {
173 copy_out_vec_be(output, output_length(), m_digest);
174 }
175
176/*
177* Clear memory of sensitive data
178*/
180 {
182 zeroise(m_W);
183 m_digest[0] = 0x67452301;
184 m_digest[1] = 0xEFCDAB89;
185 m_digest[2] = 0x98BADCFE;
186 m_digest[3] = 0x10325476;
187 m_digest[4] = 0xC3D2E1F0;
188 }
189
190}
size_t hash_block_size() const override final
Definition mdx_hash.h:35
void clear() override
Definition mdx_hash.cpp:41
void clear() override
Definition sha160.cpp:179
size_t output_length() const override
Definition sha160.h:24
std::unique_ptr< HashFunction > copy_state() const override
Definition sha160.cpp:15
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:114
T load_be(const uint8_t in[], size_t off)
Definition loadstor.h:107
void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
Definition loadstor.h:673