/src/Botan-3.4.0/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/bit_ops.h> |
12 | | #include <botan/internal/loadstor.h> |
13 | | #include <botan/internal/rotate.h> |
14 | | #include <botan/internal/stl_util.h> |
15 | | |
16 | | namespace Botan { |
17 | | |
18 | | namespace { |
19 | | |
20 | 109M | inline uint32_t P0(uint32_t X) { |
21 | 109M | return X ^ rotl<9>(X) ^ rotl<17>(X); |
22 | 109M | } |
23 | | |
24 | | inline void R1(uint32_t A, |
25 | | uint32_t& B, |
26 | | uint32_t C, |
27 | | uint32_t& D, |
28 | | uint32_t E, |
29 | | uint32_t& F, |
30 | | uint32_t G, |
31 | | uint32_t& H, |
32 | | uint32_t TJ, |
33 | | uint32_t Wi, |
34 | 27.4M | uint32_t Wj) { |
35 | 27.4M | const uint32_t A12 = rotl<12>(A); |
36 | 27.4M | const uint32_t SS1 = rotl<7>(A12 + E + TJ); |
37 | 27.4M | const uint32_t TT1 = (A ^ B ^ C) + D + (SS1 ^ A12) + Wj; |
38 | 27.4M | const uint32_t TT2 = (E ^ F ^ G) + H + SS1 + Wi; |
39 | | |
40 | 27.4M | B = rotl<9>(B); |
41 | 27.4M | D = TT1; |
42 | 27.4M | F = rotl<19>(F); |
43 | 27.4M | H = P0(TT2); |
44 | 27.4M | } |
45 | | |
46 | | inline void R2(uint32_t A, |
47 | | uint32_t& B, |
48 | | uint32_t C, |
49 | | uint32_t& D, |
50 | | uint32_t E, |
51 | | uint32_t& F, |
52 | | uint32_t G, |
53 | | uint32_t& H, |
54 | | uint32_t TJ, |
55 | | uint32_t Wi, |
56 | 82.3M | uint32_t Wj) { |
57 | 82.3M | const uint32_t A12 = rotl<12>(A); |
58 | 82.3M | const uint32_t SS1 = rotl<7>(A12 + E + TJ); |
59 | 82.3M | const uint32_t TT1 = majority(A, B, C) + D + (SS1 ^ A12) + Wj; |
60 | 82.3M | const uint32_t TT2 = choose(E, F, G) + H + SS1 + Wi; |
61 | | |
62 | 82.3M | B = rotl<9>(B); |
63 | 82.3M | D = TT1; |
64 | 82.3M | F = rotl<19>(F); |
65 | 82.3M | H = P0(TT2); |
66 | 82.3M | } |
67 | | |
68 | 89.1M | inline uint32_t P1(uint32_t X) { |
69 | 89.1M | return X ^ rotl<15>(X) ^ rotl<23>(X); |
70 | 89.1M | } |
71 | | |
72 | 89.1M | inline uint32_t SM3_E(uint32_t W0, uint32_t W7, uint32_t W13, uint32_t W3, uint32_t W10) { |
73 | 89.1M | return P1(W0 ^ W7 ^ rotl<15>(W13)) ^ rotl<7>(W3) ^ W10; |
74 | 89.1M | } |
75 | | |
76 | | } // namespace |
77 | | |
78 | | /* |
79 | | * SM3 Compression Function |
80 | | */ |
81 | 120k | void SM3::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) { |
82 | 120k | uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], G = digest[6], |
83 | 120k | H = digest[7]; |
84 | | |
85 | 120k | BufferSlicer in(input); |
86 | | |
87 | 1.83M | for(size_t i = 0; i != blocks; ++i) { |
88 | 1.71M | const auto block = in.take(block_bytes); |
89 | | |
90 | 1.71M | uint32_t W00 = load_be<uint32_t>(block.data(), 0); |
91 | 1.71M | uint32_t W01 = load_be<uint32_t>(block.data(), 1); |
92 | 1.71M | uint32_t W02 = load_be<uint32_t>(block.data(), 2); |
93 | 1.71M | uint32_t W03 = load_be<uint32_t>(block.data(), 3); |
94 | 1.71M | uint32_t W04 = load_be<uint32_t>(block.data(), 4); |
95 | 1.71M | uint32_t W05 = load_be<uint32_t>(block.data(), 5); |
96 | 1.71M | uint32_t W06 = load_be<uint32_t>(block.data(), 6); |
97 | 1.71M | uint32_t W07 = load_be<uint32_t>(block.data(), 7); |
98 | 1.71M | uint32_t W08 = load_be<uint32_t>(block.data(), 8); |
99 | 1.71M | uint32_t W09 = load_be<uint32_t>(block.data(), 9); |
100 | 1.71M | uint32_t W10 = load_be<uint32_t>(block.data(), 10); |
101 | 1.71M | uint32_t W11 = load_be<uint32_t>(block.data(), 11); |
102 | 1.71M | uint32_t W12 = load_be<uint32_t>(block.data(), 12); |
103 | 1.71M | uint32_t W13 = load_be<uint32_t>(block.data(), 13); |
104 | 1.71M | uint32_t W14 = load_be<uint32_t>(block.data(), 14); |
105 | 1.71M | uint32_t W15 = load_be<uint32_t>(block.data(), 15); |
106 | | |
107 | 1.71M | R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04); |
108 | 1.71M | W00 = SM3_E(W00, W07, W13, W03, W10); |
109 | 1.71M | R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05); |
110 | 1.71M | W01 = SM3_E(W01, W08, W14, W04, W11); |
111 | 1.71M | R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06); |
112 | 1.71M | W02 = SM3_E(W02, W09, W15, W05, W12); |
113 | 1.71M | R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07); |
114 | 1.71M | W03 = SM3_E(W03, W10, W00, W06, W13); |
115 | 1.71M | R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08); |
116 | 1.71M | W04 = SM3_E(W04, W11, W01, W07, W14); |
117 | 1.71M | R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09); |
118 | 1.71M | W05 = SM3_E(W05, W12, W02, W08, W15); |
119 | 1.71M | R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10); |
120 | 1.71M | W06 = SM3_E(W06, W13, W03, W09, W00); |
121 | 1.71M | R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11); |
122 | 1.71M | W07 = SM3_E(W07, W14, W04, W10, W01); |
123 | 1.71M | R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12); |
124 | 1.71M | W08 = SM3_E(W08, W15, W05, W11, W02); |
125 | 1.71M | R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13); |
126 | 1.71M | W09 = SM3_E(W09, W00, W06, W12, W03); |
127 | 1.71M | R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14); |
128 | 1.71M | W10 = SM3_E(W10, W01, W07, W13, W04); |
129 | 1.71M | R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15); |
130 | 1.71M | W11 = SM3_E(W11, W02, W08, W14, W05); |
131 | 1.71M | R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00); |
132 | 1.71M | W12 = SM3_E(W12, W03, W09, W15, W06); |
133 | 1.71M | R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01); |
134 | 1.71M | W13 = SM3_E(W13, W04, W10, W00, W07); |
135 | 1.71M | R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02); |
136 | 1.71M | W14 = SM3_E(W14, W05, W11, W01, W08); |
137 | 1.71M | R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03); |
138 | 1.71M | W15 = SM3_E(W15, W06, W12, W02, W09); |
139 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); |
140 | 1.71M | W00 = SM3_E(W00, W07, W13, W03, W10); |
141 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); |
142 | 1.71M | W01 = SM3_E(W01, W08, W14, W04, W11); |
143 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); |
144 | 1.71M | W02 = SM3_E(W02, W09, W15, W05, W12); |
145 | 1.71M | R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); |
146 | 1.71M | W03 = SM3_E(W03, W10, W00, W06, W13); |
147 | 1.71M | R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); |
148 | 1.71M | W04 = SM3_E(W04, W11, W01, W07, W14); |
149 | 1.71M | R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); |
150 | 1.71M | W05 = SM3_E(W05, W12, W02, W08, W15); |
151 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); |
152 | 1.71M | W06 = SM3_E(W06, W13, W03, W09, W00); |
153 | 1.71M | R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); |
154 | 1.71M | W07 = SM3_E(W07, W14, W04, W10, W01); |
155 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); |
156 | 1.71M | W08 = SM3_E(W08, W15, W05, W11, W02); |
157 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); |
158 | 1.71M | W09 = SM3_E(W09, W00, W06, W12, W03); |
159 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); |
160 | 1.71M | W10 = SM3_E(W10, W01, W07, W13, W04); |
161 | 1.71M | R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); |
162 | 1.71M | W11 = SM3_E(W11, W02, W08, W14, W05); |
163 | 1.71M | R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); |
164 | 1.71M | W12 = SM3_E(W12, W03, W09, W15, W06); |
165 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); |
166 | 1.71M | W13 = SM3_E(W13, W04, W10, W00, W07); |
167 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); |
168 | 1.71M | W14 = SM3_E(W14, W05, W11, W01, W08); |
169 | 1.71M | R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); |
170 | 1.71M | W15 = SM3_E(W15, W06, W12, W02, W09); |
171 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04); |
172 | 1.71M | W00 = SM3_E(W00, W07, W13, W03, W10); |
173 | 1.71M | R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05); |
174 | 1.71M | W01 = SM3_E(W01, W08, W14, W04, W11); |
175 | 1.71M | R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06); |
176 | 1.71M | W02 = SM3_E(W02, W09, W15, W05, W12); |
177 | 1.71M | R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07); |
178 | 1.71M | W03 = SM3_E(W03, W10, W00, W06, W13); |
179 | 1.71M | R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08); |
180 | 1.71M | W04 = SM3_E(W04, W11, W01, W07, W14); |
181 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09); |
182 | 1.71M | W05 = SM3_E(W05, W12, W02, W08, W15); |
183 | 1.71M | R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10); |
184 | 1.71M | W06 = SM3_E(W06, W13, W03, W09, W00); |
185 | 1.71M | R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11); |
186 | 1.71M | W07 = SM3_E(W07, W14, W04, W10, W01); |
187 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12); |
188 | 1.71M | W08 = SM3_E(W08, W15, W05, W11, W02); |
189 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13); |
190 | 1.71M | W09 = SM3_E(W09, W00, W06, W12, W03); |
191 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14); |
192 | 1.71M | W10 = SM3_E(W10, W01, W07, W13, W04); |
193 | 1.71M | R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15); |
194 | 1.71M | W11 = SM3_E(W11, W02, W08, W14, W05); |
195 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00); |
196 | 1.71M | W12 = SM3_E(W12, W03, W09, W15, W06); |
197 | 1.71M | R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01); |
198 | 1.71M | W13 = SM3_E(W13, W04, W10, W00, W07); |
199 | 1.71M | R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02); |
200 | 1.71M | W14 = SM3_E(W14, W05, W11, W01, W08); |
201 | 1.71M | R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03); |
202 | 1.71M | W15 = SM3_E(W15, W06, W12, W02, W09); |
203 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); |
204 | 1.71M | W00 = SM3_E(W00, W07, W13, W03, W10); |
205 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); |
206 | 1.71M | W01 = SM3_E(W01, W08, W14, W04, W11); |
207 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); |
208 | 1.71M | W02 = SM3_E(W02, W09, W15, W05, W12); |
209 | 1.71M | R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); |
210 | 1.71M | W03 = SM3_E(W03, W10, W00, W06, W13); |
211 | 1.71M | R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); |
212 | 1.71M | R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); |
213 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); |
214 | 1.71M | R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); |
215 | 1.71M | R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); |
216 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); |
217 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); |
218 | 1.71M | R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); |
219 | 1.71M | R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); |
220 | 1.71M | R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); |
221 | 1.71M | R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); |
222 | 1.71M | R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); |
223 | | |
224 | 1.71M | A = (digest[0] ^= A); |
225 | 1.71M | B = (digest[1] ^= B); |
226 | 1.71M | C = (digest[2] ^= C); |
227 | 1.71M | D = (digest[3] ^= D); |
228 | 1.71M | E = (digest[4] ^= E); |
229 | 1.71M | F = (digest[5] ^= F); |
230 | 1.71M | G = (digest[6] ^= G); |
231 | 1.71M | H = (digest[7] ^= H); |
232 | 1.71M | } |
233 | 120k | } |
234 | | |
235 | 16.5k | void SM3::init(digest_type& digest) { |
236 | 16.5k | digest.assign( |
237 | 16.5k | {0x7380166fUL, 0x4914b2b9UL, 0x172442d7UL, 0xda8a0600UL, 0xa96f30bcUL, 0x163138aaUL, 0xe38dee4dUL, 0xb0fb0e4eUL}); |
238 | 16.5k | } |
239 | | |
240 | 0 | std::unique_ptr<HashFunction> SM3::new_object() const { |
241 | 0 | return std::make_unique<SM3>(); |
242 | 0 | } |
243 | | |
244 | 0 | std::unique_ptr<HashFunction> SM3::copy_state() const { |
245 | 0 | return std::make_unique<SM3>(*this); |
246 | 0 | } |
247 | | |
248 | 5.18M | void SM3::add_data(std::span<const uint8_t> input) { |
249 | 5.18M | m_md.update(input); |
250 | 5.18M | } |
251 | | |
252 | 6.36k | void SM3::final_result(std::span<uint8_t> output) { |
253 | 6.36k | m_md.final(output); |
254 | 6.36k | } |
255 | | |
256 | | } // namespace Botan |