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