/src/botan/src/lib/hash/sm3/sm3.cpp
Line | Count | Source |
1 | | /* |
2 | | * SM3 |
3 | | * (C) 2017 Ribose Inc. |
4 | | * (C) 2021 Jack Lloyd |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #include <botan/internal/sm3.h> |
10 | | |
11 | | #include <botan/internal/buffer_slicer.h> |
12 | | #include <botan/internal/loadstor.h> |
13 | | #include <botan/internal/sm3_fn.h> |
14 | | |
15 | | #if defined(BOTAN_HAS_CPUID) |
16 | | #include <botan/internal/cpuid.h> |
17 | | #endif |
18 | | |
19 | | namespace Botan { |
20 | | |
21 | | /* |
22 | | * SM3 Compression Function |
23 | | */ |
24 | 0 | void SM3::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) { |
25 | 0 | #if defined(BOTAN_HAS_SM3_X86) |
26 | 0 | if(CPUID::has(CPUID::Feature::SM3, CPUID::Feature::AVX2)) { |
27 | 0 | return compress_digest_x86(digest, input, blocks); |
28 | 0 | } |
29 | 0 | #endif |
30 | | |
31 | 0 | #if defined(BOTAN_HAS_SM3_X86_AVX2_BMI2) |
32 | 0 | if(CPUID::has(CPUID::Feature::AVX2, CPUID::Feature::BMI)) { |
33 | 0 | return compress_digest_x86_avx2(digest, input, blocks); |
34 | 0 | } |
35 | 0 | #endif |
36 | | |
37 | 0 | uint32_t A = digest[0]; |
38 | 0 | uint32_t B = digest[1]; |
39 | 0 | uint32_t C = digest[2]; |
40 | 0 | uint32_t D = digest[3]; |
41 | 0 | uint32_t E = digest[4]; |
42 | 0 | uint32_t F = digest[5]; |
43 | 0 | uint32_t G = digest[6]; |
44 | 0 | uint32_t H = digest[7]; |
45 | 0 | std::array<uint32_t, 16> W{}; |
46 | |
|
47 | 0 | BufferSlicer in(input); |
48 | |
|
49 | 0 | for(size_t i = 0; i != blocks; ++i) { |
50 | 0 | load_be(W, in.take<block_bytes>()); |
51 | | |
52 | | // clang-format off |
53 | |
|
54 | 0 | R1(A, B, C, D, E, F, G, H, 0x79CC4519, W[ 0], W[ 4]); |
55 | 0 | W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]); |
56 | 0 | R1(D, A, B, C, H, E, F, G, 0xF3988A32, W[ 1], W[ 5]); |
57 | 0 | W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]); |
58 | 0 | R1(C, D, A, B, G, H, E, F, 0xE7311465, W[ 2], W[ 6]); |
59 | 0 | W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]); |
60 | 0 | R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W[ 3], W[ 7]); |
61 | 0 | W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]); |
62 | 0 | R1(A, B, C, D, E, F, G, H, 0x9CC45197, W[ 4], W[ 8]); |
63 | 0 | W[ 4] = SM3_E(W[ 4], W[11], W[ 1], W[ 7], W[14]); |
64 | 0 | R1(D, A, B, C, H, E, F, G, 0x3988A32F, W[ 5], W[ 9]); |
65 | 0 | W[ 5] = SM3_E(W[ 5], W[12], W[ 2], W[ 8], W[15]); |
66 | 0 | R1(C, D, A, B, G, H, E, F, 0x7311465E, W[ 6], W[10]); |
67 | 0 | W[ 6] = SM3_E(W[ 6], W[13], W[ 3], W[ 9], W[ 0]); |
68 | 0 | R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W[ 7], W[11]); |
69 | 0 | W[ 7] = SM3_E(W[ 7], W[14], W[ 4], W[10], W[ 1]); |
70 | 0 | R1(A, B, C, D, E, F, G, H, 0xCC451979, W[ 8], W[12]); |
71 | 0 | W[ 8] = SM3_E(W[ 8], W[15], W[ 5], W[11], W[ 2]); |
72 | 0 | R1(D, A, B, C, H, E, F, G, 0x988A32F3, W[ 9], W[13]); |
73 | 0 | W[ 9] = SM3_E(W[ 9], W[ 0], W[ 6], W[12], W[ 3]); |
74 | 0 | R1(C, D, A, B, G, H, E, F, 0x311465E7, W[10], W[14]); |
75 | 0 | W[10] = SM3_E(W[10], W[ 1], W[ 7], W[13], W[ 4]); |
76 | 0 | R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W[11], W[15]); |
77 | 0 | W[11] = SM3_E(W[11], W[ 2], W[ 8], W[14], W[ 5]); |
78 | 0 | R1(A, B, C, D, E, F, G, H, 0xC451979C, W[12], W[ 0]); |
79 | 0 | W[12] = SM3_E(W[12], W[ 3], W[ 9], W[15], W[ 6]); |
80 | 0 | R1(D, A, B, C, H, E, F, G, 0x88A32F39, W[13], W[ 1]); |
81 | 0 | W[13] = SM3_E(W[13], W[ 4], W[10], W[ 0], W[ 7]); |
82 | 0 | R1(C, D, A, B, G, H, E, F, 0x11465E73, W[14], W[ 2]); |
83 | 0 | W[14] = SM3_E(W[14], W[ 5], W[11], W[ 1], W[ 8]); |
84 | 0 | R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W[15], W[ 3]); |
85 | 0 | W[15] = SM3_E(W[15], W[ 6], W[12], W[ 2], W[ 9]); |
86 | 0 | R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W[ 0], W[ 4]); |
87 | 0 | W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]); |
88 | 0 | R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W[ 1], W[ 5]); |
89 | 0 | W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]); |
90 | 0 | R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W[ 2], W[ 6]); |
91 | 0 | W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]); |
92 | 0 | R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W[ 3], W[ 7]); |
93 | 0 | W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]); |
94 | 0 | R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W[ 4], W[ 8]); |
95 | 0 | W[ 4] = SM3_E(W[ 4], W[11], W[ 1], W[ 7], W[14]); |
96 | 0 | R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W[ 5], W[ 9]); |
97 | 0 | W[ 5] = SM3_E(W[ 5], W[12], W[ 2], W[ 8], W[15]); |
98 | 0 | R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W[ 6], W[10]); |
99 | 0 | W[ 6] = SM3_E(W[ 6], W[13], W[ 3], W[ 9], W[ 0]); |
100 | 0 | R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W[ 7], W[11]); |
101 | 0 | W[ 7] = SM3_E(W[ 7], W[14], W[ 4], W[10], W[ 1]); |
102 | 0 | R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W[ 8], W[12]); |
103 | 0 | W[ 8] = SM3_E(W[ 8], W[15], W[ 5], W[11], W[ 2]); |
104 | 0 | R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W[ 9], W[13]); |
105 | 0 | W[ 9] = SM3_E(W[ 9], W[ 0], W[ 6], W[12], W[ 3]); |
106 | 0 | R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W[10], W[14]); |
107 | 0 | W[10] = SM3_E(W[10], W[ 1], W[ 7], W[13], W[ 4]); |
108 | 0 | R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W[11], W[15]); |
109 | 0 | W[11] = SM3_E(W[11], W[ 2], W[ 8], W[14], W[ 5]); |
110 | 0 | R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W[12], W[ 0]); |
111 | 0 | W[12] = SM3_E(W[12], W[ 3], W[ 9], W[15], W[ 6]); |
112 | 0 | R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W[13], W[ 1]); |
113 | 0 | W[13] = SM3_E(W[13], W[ 4], W[10], W[ 0], W[ 7]); |
114 | 0 | R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W[14], W[ 2]); |
115 | 0 | W[14] = SM3_E(W[14], W[ 5], W[11], W[ 1], W[ 8]); |
116 | 0 | R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W[15], W[ 3]); |
117 | 0 | W[15] = SM3_E(W[15], W[ 6], W[12], W[ 2], W[ 9]); |
118 | 0 | R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W[ 0], W[ 4]); |
119 | 0 | W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]); |
120 | 0 | R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W[ 1], W[ 5]); |
121 | 0 | W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]); |
122 | 0 | R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W[ 2], W[ 6]); |
123 | 0 | W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]); |
124 | 0 | R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W[ 3], W[ 7]); |
125 | 0 | W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]); |
126 | 0 | R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W[ 4], W[ 8]); |
127 | 0 | W[ 4] = SM3_E(W[ 4], W[11], W[ 1], W[ 7], W[14]); |
128 | 0 | R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W[ 5], W[ 9]); |
129 | 0 | W[ 5] = SM3_E(W[ 5], W[12], W[ 2], W[ 8], W[15]); |
130 | 0 | R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W[ 6], W[10]); |
131 | 0 | W[ 6] = SM3_E(W[ 6], W[13], W[ 3], W[ 9], W[ 0]); |
132 | 0 | R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W[ 7], W[11]); |
133 | 0 | W[ 7] = SM3_E(W[ 7], W[14], W[ 4], W[10], W[ 1]); |
134 | 0 | R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W[ 8], W[12]); |
135 | 0 | W[ 8] = SM3_E(W[ 8], W[15], W[ 5], W[11], W[ 2]); |
136 | 0 | R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W[ 9], W[13]); |
137 | 0 | W[ 9] = SM3_E(W[ 9], W[ 0], W[ 6], W[12], W[ 3]); |
138 | 0 | R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W[10], W[14]); |
139 | 0 | W[10] = SM3_E(W[10], W[ 1], W[ 7], W[13], W[ 4]); |
140 | 0 | R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W[11], W[15]); |
141 | 0 | W[11] = SM3_E(W[11], W[ 2], W[ 8], W[14], W[ 5]); |
142 | 0 | R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W[12], W[ 0]); |
143 | 0 | W[12] = SM3_E(W[12], W[ 3], W[ 9], W[15], W[ 6]); |
144 | 0 | R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W[13], W[ 1]); |
145 | 0 | W[13] = SM3_E(W[13], W[ 4], W[10], W[ 0], W[ 7]); |
146 | 0 | R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W[14], W[ 2]); |
147 | 0 | W[14] = SM3_E(W[14], W[ 5], W[11], W[ 1], W[ 8]); |
148 | 0 | R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W[15], W[ 3]); |
149 | 0 | W[15] = SM3_E(W[15], W[ 6], W[12], W[ 2], W[ 9]); |
150 | 0 | R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W[ 0], W[ 4]); |
151 | 0 | W[ 0] = SM3_E(W[ 0], W[ 7], W[13], W[ 3], W[10]); |
152 | 0 | R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W[ 1], W[ 5]); |
153 | 0 | W[ 1] = SM3_E(W[ 1], W[ 8], W[14], W[ 4], W[11]); |
154 | 0 | R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W[ 2], W[ 6]); |
155 | 0 | W[ 2] = SM3_E(W[ 2], W[ 9], W[15], W[ 5], W[12]); |
156 | 0 | R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W[ 3], W[ 7]); |
157 | 0 | W[ 3] = SM3_E(W[ 3], W[10], W[ 0], W[ 6], W[13]); |
158 | 0 | R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W[ 4], W[ 8]); |
159 | 0 | R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W[ 5], W[ 9]); |
160 | 0 | R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W[ 6], W[10]); |
161 | 0 | R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W[ 7], W[11]); |
162 | 0 | R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W[ 8], W[12]); |
163 | 0 | R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W[ 9], W[13]); |
164 | 0 | R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W[10], W[14]); |
165 | 0 | R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W[11], W[15]); |
166 | 0 | R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W[12], W[ 0]); |
167 | 0 | R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W[13], W[ 1]); |
168 | 0 | R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W[14], W[ 2]); |
169 | 0 | R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W[15], W[ 3]); |
170 | | |
171 | | // clang-format on |
172 | |
|
173 | 0 | A = (digest[0] ^= A); |
174 | 0 | B = (digest[1] ^= B); |
175 | 0 | C = (digest[2] ^= C); |
176 | 0 | D = (digest[3] ^= D); |
177 | 0 | E = (digest[4] ^= E); |
178 | 0 | F = (digest[5] ^= F); |
179 | 0 | G = (digest[6] ^= G); |
180 | 0 | H = (digest[7] ^= H); |
181 | 0 | } |
182 | 0 | } |
183 | | |
184 | 0 | void SM3::init(digest_type& digest) { |
185 | 0 | digest.assign( |
186 | 0 | {0x7380166fUL, 0x4914b2b9UL, 0x172442d7UL, 0xda8a0600UL, 0xa96f30bcUL, 0x163138aaUL, 0xe38dee4dUL, 0xb0fb0e4eUL}); |
187 | 0 | } |
188 | | |
189 | 0 | std::unique_ptr<HashFunction> SM3::new_object() const { |
190 | 0 | return std::make_unique<SM3>(); |
191 | 0 | } |
192 | | |
193 | 0 | std::unique_ptr<HashFunction> SM3::copy_state() const { |
194 | 0 | return std::make_unique<SM3>(*this); |
195 | 0 | } |
196 | | |
197 | 0 | void SM3::add_data(std::span<const uint8_t> input) { |
198 | 0 | m_md.update(input); |
199 | 0 | } |
200 | | |
201 | 0 | void SM3::final_result(std::span<uint8_t> output) { |
202 | 0 | m_md.final(output); |
203 | 0 | } |
204 | | |
205 | 0 | std::string SM3::provider() const { |
206 | 0 | #if defined(BOTAN_HAS_SM3_X86) |
207 | 0 | if(auto feat = CPUID::check(CPUID::Feature::SM3, CPUID::Feature::AVX2)) { |
208 | 0 | return *feat; |
209 | 0 | } |
210 | 0 | #endif |
211 | | |
212 | 0 | #if defined(BOTAN_HAS_SM3_X86_AVX2_BMI2) |
213 | 0 | if(auto feat = CPUID::check(CPUID::Feature::AVX2, CPUID::Feature::BMI)) { |
214 | 0 | return *feat; |
215 | 0 | } |
216 | 0 | #endif |
217 | | |
218 | 0 | return "base"; |
219 | 0 | } |
220 | | |
221 | | } // namespace Botan |