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