/src/nettle-with-libgmp/sm3.c
Line | Count | Source |
1 | | /* sm3.c |
2 | | |
3 | | The SM3 hash function. |
4 | | |
5 | | Copyright (C) 2017 Jia Zhang |
6 | | Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com> |
7 | | |
8 | | This file is part of GNU Nettle. |
9 | | |
10 | | GNU Nettle is free software: you can redistribute it and/or |
11 | | modify it under the terms of either: |
12 | | |
13 | | * the GNU Lesser General Public License as published by the Free |
14 | | Software Foundation; either version 3 of the License, or (at your |
15 | | option) any later version. |
16 | | |
17 | | or |
18 | | |
19 | | * the GNU General Public License as published by the Free |
20 | | Software Foundation; either version 2 of the License, or (at your |
21 | | option) any later version. |
22 | | |
23 | | or both in parallel, as here. |
24 | | |
25 | | GNU Nettle is distributed in the hope that it will be useful, |
26 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
28 | | General Public License for more details. |
29 | | |
30 | | You should have received copies of the GNU General Public License and |
31 | | the GNU Lesser General Public License along with this program. If |
32 | | not, see http://www.gnu.org/licenses/. |
33 | | */ |
34 | | |
35 | | #if HAVE_CONFIG_H |
36 | | # include "config.h" |
37 | | #endif |
38 | | |
39 | | #include <assert.h> |
40 | | #include <string.h> |
41 | | |
42 | | #include "sm3.h" |
43 | | |
44 | | #include "macros.h" |
45 | | #include "nettle-write.h" |
46 | | |
47 | | static const uint32_t K[64] = |
48 | | { |
49 | | 0x79cc4519UL, 0xf3988a32UL, 0xe7311465UL, 0xce6228cbUL, |
50 | | 0x9cc45197UL, 0x3988a32fUL, 0x7311465eUL, 0xe6228cbcUL, |
51 | | 0xcc451979UL, 0x988a32f3UL, 0x311465e7UL, 0x6228cbceUL, |
52 | | 0xc451979cUL, 0x88a32f39UL, 0x11465e73UL, 0x228cbce6UL, |
53 | | 0x9d8a7a87UL, 0x3b14f50fUL, 0x7629ea1eUL, 0xec53d43cUL, |
54 | | 0xd8a7a879UL, 0xb14f50f3UL, 0x629ea1e7UL, 0xc53d43ceUL, |
55 | | 0x8a7a879dUL, 0x14f50f3bUL, 0x29ea1e76UL, 0x53d43cecUL, |
56 | | 0xa7a879d8UL, 0x4f50f3b1UL, 0x9ea1e762UL, 0x3d43cec5UL, |
57 | | 0x7a879d8aUL, 0xf50f3b14UL, 0xea1e7629UL, 0xd43cec53UL, |
58 | | 0xa879d8a7UL, 0x50f3b14fUL, 0xa1e7629eUL, 0x43cec53dUL, |
59 | | 0x879d8a7aUL, 0x0f3b14f5UL, 0x1e7629eaUL, 0x3cec53d4UL, |
60 | | 0x79d8a7a8UL, 0xf3b14f50UL, 0xe7629ea1UL, 0xcec53d43UL, |
61 | | 0x9d8a7a87UL, 0x3b14f50fUL, 0x7629ea1eUL, 0xec53d43cUL, |
62 | | 0xd8a7a879UL, 0xb14f50f3UL, 0x629ea1e7UL, 0xc53d43ceUL, |
63 | | 0x8a7a879dUL, 0x14f50f3bUL, 0x29ea1e76UL, 0x53d43cecUL, |
64 | | 0xa7a879d8UL, 0x4f50f3b1UL, 0x9ea1e762UL, 0x3d43cec5UL |
65 | | }; |
66 | | |
67 | | /* |
68 | | Transform the message X which consists of 16 32-bit-words. See |
69 | | GM/T 004-2012 for details. */ |
70 | | #define R(i, a, b, c, d, e, f, g, h, t, w1, w2) \ |
71 | 3.33M | do { \ |
72 | 3.33M | ss1 = ROTL32(7, (ROTL32(12, (a)) + (e) + (t))); \ |
73 | 3.33M | ss2 = ss1 ^ ROTL32(12, (a)); \ |
74 | 3.33M | d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2)); \ |
75 | 3.33M | h += GG ## i(e, f, g) + ss1 + (w1); \ |
76 | 3.33M | b = ROTL32(9, (b)); \ |
77 | 3.33M | f = ROTL32(19, (f)); \ |
78 | 3.33M | h = P0((h)); \ |
79 | 3.33M | } while (0) |
80 | | |
81 | 834k | #define R1(a,b,c,d,e,f,g,h,t,w1,w2) R(1,a,b,c,d,e,f,g,h,t,w1,w2) |
82 | 2.50M | #define R2(a,b,c,d,e,f,g,h,t,w1,w2) R(2,a,b,c,d,e,f,g,h,t,w1,w2) |
83 | | |
84 | 834k | #define FF1(x, y, z) (x ^ y ^ z) |
85 | 2.50M | #define FF2(x, y, z) ((x & y) | (x & z) | (y & z)) |
86 | | |
87 | 834k | #define GG1(x, y, z) (x ^ y ^ z) |
88 | 2.50M | #define GG2(x, y, z) ((x & y) | ( ~x & z)) |
89 | | |
90 | | /* Message expansion */ |
91 | 3.33M | #define P0(x) ((x) ^ ROTL32(9, (x)) ^ ROTL32(17, (x))) |
92 | | #define P1(x) ((x) ^ ROTL32(15, (x)) ^ ROTL32(23, (x))) |
93 | | #define I(i) (w[i] = READ_UINT32(input + i * 4)) |
94 | | #define W1(i) (w[i & 0x0f]) |
95 | | #define W2(i) (w[i & 0x0f] = \ |
96 | | P1(w[i & 0x0f] ^ w[(i-9) & 0x0f] ^ ROTL32(15, w[(i-3) & 0x0f])) \ |
97 | | ^ ROTL32(7, w[(i-13) & 0x0f]) \ |
98 | | ^ w[(i-6) & 0x0f]) |
99 | | |
100 | | |
101 | | static void |
102 | | sm3_compress(uint32_t *state, const uint8_t *input) |
103 | 52.1k | { |
104 | 52.1k | uint32_t a, b, c, d, e, f, g, h, ss1, ss2; |
105 | 52.1k | uint32_t w[16]; |
106 | | |
107 | 52.1k | a = state[0]; |
108 | 52.1k | b = state[1]; |
109 | 52.1k | c = state[2]; |
110 | 52.1k | d = state[3]; |
111 | 52.1k | e = state[4]; |
112 | 52.1k | f = state[5]; |
113 | 52.1k | g = state[6]; |
114 | 52.1k | h = state[7]; |
115 | | |
116 | 52.1k | R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4)); |
117 | 52.1k | R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5)); |
118 | 52.1k | R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6)); |
119 | 52.1k | R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7)); |
120 | 52.1k | R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8)); |
121 | 52.1k | R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9)); |
122 | 52.1k | R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10)); |
123 | 52.1k | R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11)); |
124 | 52.1k | R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12)); |
125 | 52.1k | R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13)); |
126 | 52.1k | R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14)); |
127 | 52.1k | R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15)); |
128 | 52.1k | R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16)); |
129 | 52.1k | R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17)); |
130 | 52.1k | R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18)); |
131 | 52.1k | R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19)); |
132 | | |
133 | 52.1k | R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20)); |
134 | 52.1k | R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21)); |
135 | 52.1k | R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22)); |
136 | 52.1k | R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23)); |
137 | 52.1k | R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24)); |
138 | 52.1k | R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25)); |
139 | 52.1k | R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26)); |
140 | 52.1k | R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27)); |
141 | 52.1k | R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28)); |
142 | 52.1k | R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29)); |
143 | 52.1k | R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30)); |
144 | 52.1k | R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31)); |
145 | 52.1k | R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32)); |
146 | 52.1k | R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33)); |
147 | 52.1k | R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34)); |
148 | 52.1k | R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35)); |
149 | | |
150 | 52.1k | R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36)); |
151 | 52.1k | R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37)); |
152 | 52.1k | R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38)); |
153 | 52.1k | R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39)); |
154 | 52.1k | R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40)); |
155 | 52.1k | R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41)); |
156 | 52.1k | R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42)); |
157 | 52.1k | R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43)); |
158 | 52.1k | R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44)); |
159 | 52.1k | R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45)); |
160 | 52.1k | R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46)); |
161 | 52.1k | R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47)); |
162 | 52.1k | R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48)); |
163 | 52.1k | R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49)); |
164 | 52.1k | R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50)); |
165 | 52.1k | R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51)); |
166 | | |
167 | 52.1k | R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52)); |
168 | 52.1k | R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53)); |
169 | 52.1k | R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54)); |
170 | 52.1k | R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55)); |
171 | 52.1k | R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56)); |
172 | 52.1k | R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57)); |
173 | 52.1k | R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58)); |
174 | 52.1k | R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59)); |
175 | 52.1k | R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60)); |
176 | 52.1k | R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61)); |
177 | 52.1k | R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62)); |
178 | 52.1k | R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63)); |
179 | 52.1k | R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64)); |
180 | 52.1k | R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65)); |
181 | 52.1k | R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66)); |
182 | 52.1k | R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67)); |
183 | | |
184 | 52.1k | state[0] ^= a; |
185 | 52.1k | state[1] ^= b; |
186 | 52.1k | state[2] ^= c; |
187 | 52.1k | state[3] ^= d; |
188 | 52.1k | state[4] ^= e; |
189 | 52.1k | state[5] ^= f; |
190 | 52.1k | state[6] ^= g; |
191 | 52.1k | state[7] ^= h; |
192 | 52.1k | } |
193 | | |
194 | | void |
195 | | sm3_init(struct sm3_ctx *ctx) |
196 | 35.8k | { |
197 | 35.8k | static const uint32_t H0[_SM3_DIGEST_LENGTH] = |
198 | 35.8k | { |
199 | 35.8k | 0x7380166fUL, 0x4914b2b9UL, 0x172442d7UL, 0xda8a0600UL, |
200 | 35.8k | 0xa96f30bcUL, 0x163138aaUL, 0xe38dee4dUL, 0xb0fb0e4eUL |
201 | 35.8k | }; |
202 | | |
203 | 35.8k | memcpy(ctx->state, H0, sizeof(H0)); |
204 | | |
205 | | /* Initialize bit count */ |
206 | 35.8k | ctx->count = 0; |
207 | | |
208 | | /* Initialize buffer */ |
209 | 35.8k | ctx->index = 0; |
210 | 35.8k | } |
211 | | |
212 | 52.1k | #define COMPRESS(ctx, data) (sm3_compress((ctx)->state, (data))) |
213 | | |
214 | | void |
215 | | sm3_update(struct sm3_ctx *ctx, |
216 | | size_t length, const uint8_t *data) |
217 | 77.1k | { |
218 | 77.1k | MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++); |
219 | 77.1k | } |
220 | | |
221 | | static void |
222 | | sm3_write_digest(struct sm3_ctx *ctx, |
223 | | size_t length, |
224 | | uint8_t *digest) |
225 | 34.6k | { |
226 | 34.6k | uint64_t bit_count; |
227 | | |
228 | 34.6k | assert(length <= SM3_DIGEST_SIZE); |
229 | | |
230 | 34.6k | MD_PAD(ctx, 8, COMPRESS); |
231 | | |
232 | | /* There are 512 = 2^9 bits in one block */ |
233 | 34.6k | bit_count = (ctx->count << 9) | (ctx->index << 3); |
234 | | |
235 | | /* This is slightly inefficient, as the numbers are converted to |
236 | | big-endian format, and will be converted back by the compression |
237 | | function. It's probably not worth the effort to fix this. */ |
238 | 34.6k | WRITE_UINT64(ctx->block + (SM3_BLOCK_SIZE - 8), bit_count); |
239 | 34.6k | COMPRESS(ctx, ctx->block); |
240 | | |
241 | 34.6k | _nettle_write_be32(length, digest, ctx->state); |
242 | 34.6k | } |
243 | | |
244 | | void |
245 | | sm3_digest(struct sm3_ctx *ctx, |
246 | | size_t length, |
247 | | uint8_t *digest) |
248 | 34.6k | { |
249 | 34.6k | sm3_write_digest(ctx, length, digest); |
250 | 34.6k | sm3_init(ctx); |
251 | 34.6k | } |