Line | Count | Source (jump to first uncovered line) |
1 | | // sm3.cpp - written and placed in the public domain by Jeffrey Walton and Han Lulu |
2 | | // Based on the specification provided by Sean Shen and Xiaodong Lee. |
3 | | // Based on code by Krzysztof Kwiatkowski and Jack Lloyd. |
4 | | // Also see https://tools.ietf.org/html/draft-shen-sm3-hash. |
5 | | // |
6 | | // We understand future ARMv8 enhancements are supposed |
7 | | // to include SM3 and SM4 related instructions so the function |
8 | | // is stubbed for an eventual SM3_HashMultipleBlocks_ARMV8. |
9 | | |
10 | | #include "pch.h" |
11 | | #include "config.h" |
12 | | |
13 | | #include "sm3.h" |
14 | | #include "misc.h" |
15 | | #include "cpu.h" |
16 | | |
17 | | ANONYMOUS_NAMESPACE_BEGIN |
18 | | |
19 | | using CryptoPP::byte; |
20 | | using CryptoPP::word32; |
21 | | using CryptoPP::rotlConstant; |
22 | | |
23 | | using CryptoPP::SM3; |
24 | | using CryptoPP::GetBlock; |
25 | | using CryptoPP::BigEndian; |
26 | | |
27 | | inline word32 P0(word32 X) |
28 | 37.5M | { |
29 | 37.5M | return X ^ rotlConstant<9>(X) ^ rotlConstant<17>(X); |
30 | 37.5M | } |
31 | | |
32 | | inline word32 P1(word32 X) |
33 | 30.4M | { |
34 | 30.4M | return X ^ rotlConstant<15>(X) ^ rotlConstant<23>(X); |
35 | 30.4M | } |
36 | | |
37 | | inline word32 EE(word32 W0, word32 W7, word32 W13, word32 W3, word32 W10) |
38 | 30.4M | { |
39 | 30.4M | return P1(W0 ^ W7 ^ rotlConstant<15>(W13)) ^ rotlConstant<7>(W3) ^ W10; |
40 | 30.4M | } |
41 | | |
42 | | inline word32 FF(word32 X, word32 Y, word32 Z) |
43 | 28.1M | { |
44 | 28.1M | return (X & Y) | ((X | Y) & Z); |
45 | 28.1M | } |
46 | | |
47 | | inline word32 GG(word32 X, word32 Y, word32 Z) |
48 | 28.1M | { |
49 | 28.1M | return ((Z ^ (X & (Y ^ Z)))); |
50 | 28.1M | } |
51 | | |
52 | | inline void R1(word32 A, word32& B, word32 C, word32& D, word32 E, word32& F, |
53 | | word32 G, word32& H, word32 TJ, word32 Wi, word32 Wj) |
54 | 9.37M | { |
55 | 9.37M | const word32 A12 = rotlConstant<12>(A); |
56 | 9.37M | const word32 TT0 = rotlConstant<7>(A12 + E + TJ); |
57 | 9.37M | const word32 TT1 = (A ^ B ^ C) + D + (TT0 ^ A12) + Wj; |
58 | 9.37M | const word32 TT2 = (E ^ F ^ G) + H + TT0 + Wi; |
59 | | |
60 | 9.37M | B = rotlConstant<9>(B); D = TT1; |
61 | 9.37M | F = rotlConstant<19>(F); H = P0(TT2); |
62 | 9.37M | } |
63 | | |
64 | | inline void R2(word32 A, word32& B, word32 C, word32& D, word32 E, word32& F, |
65 | | word32 G, word32& H, word32 TJ, word32 Wi, word32 Wj) |
66 | 28.1M | { |
67 | 28.1M | const word32 A12 = rotlConstant<12>(A); |
68 | 28.1M | const word32 TT0 = rotlConstant<7>(A12 + E + TJ); |
69 | 28.1M | const word32 TT1 = FF(A, B, C) + D + (TT0 ^ A12) + Wj; |
70 | 28.1M | const word32 TT2 = GG(E, F, G) + H + TT0 + Wi; |
71 | | |
72 | 28.1M | B = rotlConstant<9>(B); D = TT1; |
73 | 28.1M | F = rotlConstant<19>(F); H = P0(TT2); |
74 | 28.1M | } |
75 | | |
76 | | // Krzysztof Kwiatkowski did a very nice job with this function. |
77 | | size_t SM3_HashMultipleBlocks_CXX(word32 *state, const word32 *data, size_t length) |
78 | 30.4k | { |
79 | 30.4k | CRYPTOPP_ASSERT(data); |
80 | | |
81 | 30.4k | word32 A = state[0], B = state[1], C = state[2], D = state[3]; |
82 | 30.4k | word32 E = state[4], F = state[5], G = state[6], H = state[7]; |
83 | | |
84 | 616k | while (length >= SM3::BLOCKSIZE) |
85 | 586k | { |
86 | | // Reverse bytes on LittleEndian; align pointer on BigEndian |
87 | 586k | typedef GetBlock<word32, BigEndian, false> InBlock; |
88 | 586k | InBlock iblk(data); |
89 | | |
90 | 586k | word32 W00, W01, W02, W03, W04, W05, W06, W07, W08, W09, W10, W11, W12, W13, W14, W15; |
91 | 586k | iblk(W00)(W01)(W02)(W03)(W04)(W05)(W06)(W07)(W08)(W09)(W10)(W11)(W12)(W13)(W14)(W15); |
92 | | |
93 | 586k | R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04); |
94 | 586k | W00 = EE(W00, W07, W13, W03, W10); |
95 | 586k | R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05); |
96 | 586k | W01 = EE(W01, W08, W14, W04, W11); |
97 | 586k | R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06); |
98 | 586k | W02 = EE(W02, W09, W15, W05, W12); |
99 | 586k | R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07); |
100 | 586k | W03 = EE(W03, W10, W00, W06, W13); |
101 | 586k | R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08); |
102 | 586k | W04 = EE(W04, W11, W01, W07, W14); |
103 | 586k | R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09); |
104 | 586k | W05 = EE(W05, W12, W02, W08, W15); |
105 | 586k | R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10); |
106 | 586k | W06 = EE(W06, W13, W03, W09, W00); |
107 | 586k | R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11); |
108 | 586k | W07 = EE(W07, W14, W04, W10, W01); |
109 | 586k | R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12); |
110 | 586k | W08 = EE(W08, W15, W05, W11, W02); |
111 | 586k | R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13); |
112 | 586k | W09 = EE(W09, W00, W06, W12, W03); |
113 | 586k | R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14); |
114 | 586k | W10 = EE(W10, W01, W07, W13, W04); |
115 | 586k | R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15); |
116 | 586k | W11 = EE(W11, W02, W08, W14, W05); |
117 | 586k | R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00); |
118 | 586k | W12 = EE(W12, W03, W09, W15, W06); |
119 | 586k | R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01); |
120 | 586k | W13 = EE(W13, W04, W10, W00, W07); |
121 | 586k | R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02); |
122 | 586k | W14 = EE(W14, W05, W11, W01, W08); |
123 | 586k | R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03); |
124 | 586k | W15 = EE(W15, W06, W12, W02, W09); |
125 | 586k | R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); |
126 | 586k | W00 = EE(W00, W07, W13, W03, W10); |
127 | 586k | R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); |
128 | 586k | W01 = EE(W01, W08, W14, W04, W11); |
129 | 586k | R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); |
130 | 586k | W02 = EE(W02, W09, W15, W05, W12); |
131 | 586k | R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); |
132 | 586k | W03 = EE(W03, W10, W00, W06, W13); |
133 | 586k | R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); |
134 | 586k | W04 = EE(W04, W11, W01, W07, W14); |
135 | 586k | R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); |
136 | 586k | W05 = EE(W05, W12, W02, W08, W15); |
137 | 586k | R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); |
138 | 586k | W06 = EE(W06, W13, W03, W09, W00); |
139 | 586k | R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); |
140 | 586k | W07 = EE(W07, W14, W04, W10, W01); |
141 | 586k | R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); |
142 | 586k | W08 = EE(W08, W15, W05, W11, W02); |
143 | 586k | R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); |
144 | 586k | W09 = EE(W09, W00, W06, W12, W03); |
145 | 586k | R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); |
146 | 586k | W10 = EE(W10, W01, W07, W13, W04); |
147 | 586k | R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); |
148 | 586k | W11 = EE(W11, W02, W08, W14, W05); |
149 | 586k | R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); |
150 | 586k | W12 = EE(W12, W03, W09, W15, W06); |
151 | 586k | R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); |
152 | 586k | W13 = EE(W13, W04, W10, W00, W07); |
153 | 586k | R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); |
154 | 586k | W14 = EE(W14, W05, W11, W01, W08); |
155 | 586k | R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); |
156 | 586k | W15 = EE(W15, W06, W12, W02, W09); |
157 | 586k | R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04); |
158 | 586k | W00 = EE(W00, W07, W13, W03, W10); |
159 | 586k | R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05); |
160 | 586k | W01 = EE(W01, W08, W14, W04, W11); |
161 | 586k | R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06); |
162 | 586k | W02 = EE(W02, W09, W15, W05, W12); |
163 | 586k | R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07); |
164 | 586k | W03 = EE(W03, W10, W00, W06, W13); |
165 | 586k | R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08); |
166 | 586k | W04 = EE(W04, W11, W01, W07, W14); |
167 | 586k | R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09); |
168 | 586k | W05 = EE(W05, W12, W02, W08, W15); |
169 | 586k | R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10); |
170 | 586k | W06 = EE(W06, W13, W03, W09, W00); |
171 | 586k | R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11); |
172 | 586k | W07 = EE(W07, W14, W04, W10, W01); |
173 | 586k | R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12); |
174 | 586k | W08 = EE(W08, W15, W05, W11, W02); |
175 | 586k | R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13); |
176 | 586k | W09 = EE(W09, W00, W06, W12, W03); |
177 | 586k | R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14); |
178 | 586k | W10 = EE(W10, W01, W07, W13, W04); |
179 | 586k | R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15); |
180 | 586k | W11 = EE(W11, W02, W08, W14, W05); |
181 | 586k | R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00); |
182 | 586k | W12 = EE(W12, W03, W09, W15, W06); |
183 | 586k | R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01); |
184 | 586k | W13 = EE(W13, W04, W10, W00, W07); |
185 | 586k | R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02); |
186 | 586k | W14 = EE(W14, W05, W11, W01, W08); |
187 | 586k | R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03); |
188 | 586k | W15 = EE(W15, W06, W12, W02, W09); |
189 | 586k | R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); |
190 | 586k | W00 = EE(W00, W07, W13, W03, W10); |
191 | 586k | R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); |
192 | 586k | W01 = EE(W01, W08, W14, W04, W11); |
193 | 586k | R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); |
194 | 586k | W02 = EE(W02, W09, W15, W05, W12); |
195 | 586k | R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); |
196 | 586k | W03 = EE(W03, W10, W00, W06, W13); |
197 | 586k | R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); |
198 | 586k | R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); |
199 | 586k | R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); |
200 | 586k | R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); |
201 | 586k | R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); |
202 | 586k | R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); |
203 | 586k | R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); |
204 | 586k | R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); |
205 | 586k | R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); |
206 | 586k | R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); |
207 | 586k | R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); |
208 | 586k | R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); |
209 | | |
210 | 586k | A = (state[0] ^= A); |
211 | 586k | B = (state[1] ^= B); |
212 | 586k | C = (state[2] ^= C); |
213 | 586k | D = (state[3] ^= D); |
214 | 586k | E = (state[4] ^= E); |
215 | 586k | F = (state[5] ^= F); |
216 | 586k | G = (state[6] ^= G); |
217 | 586k | H = (state[7] ^= H); |
218 | | |
219 | 586k | data += SM3::BLOCKSIZE/sizeof(word32); |
220 | 586k | length -= SM3::BLOCKSIZE; |
221 | 586k | } |
222 | | |
223 | 30.4k | return length; |
224 | 30.4k | } |
225 | | |
226 | | ANONYMOUS_NAMESPACE_END |
227 | | |
228 | | NAMESPACE_BEGIN(CryptoPP) |
229 | | |
230 | | void SM3::InitState(HashWordType *state) |
231 | 12.3k | { |
232 | 12.3k | const word32 s[] = { |
233 | 12.3k | 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, |
234 | 12.3k | 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e |
235 | 12.3k | }; |
236 | | |
237 | 12.3k | std::memcpy(state, s, sizeof(s)); |
238 | 12.3k | } |
239 | | |
240 | | void SM3::Transform(word32 *state, const word32 *data) |
241 | 0 | { |
242 | 0 | CRYPTOPP_ASSERT(state); |
243 | 0 | CRYPTOPP_ASSERT(data); |
244 | |
|
245 | 0 | SM3_HashMultipleBlocks_CXX(state, data, SM3::BLOCKSIZE); |
246 | 0 | } |
247 | | |
248 | | size_t SM3::HashMultipleBlocks(const HashWordType *input, size_t length) |
249 | 30.4k | { |
250 | 30.4k | const size_t res = length & (SM3::BLOCKSIZE - 1); |
251 | 30.4k | SM3_HashMultipleBlocks_CXX(m_state, input, length-res); |
252 | 30.4k | return res; |
253 | 30.4k | } |
254 | | |
255 | | NAMESPACE_END |