Mercurial > dropbear
comparison libtomcrypt/src/hashes/sha3.c @ 1471:6dba84798cd5
Update to libtomcrypt 1.18.1, merged with Dropbear changes
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 21:44:05 +0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1470:8bba51a55704 | 1471:6dba84798cd5 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 */ | |
9 | |
10 /* based on https://github.com/brainhub/SHA3IUF (public domain) */ | |
11 | |
12 #include "tomcrypt.h" | |
13 | |
14 #ifdef LTC_SHA3 | |
15 | |
16 const struct ltc_hash_descriptor sha3_224_desc = | |
17 { | |
18 "sha3-224", /* name of hash */ | |
19 17, /* internal ID */ | |
20 28, /* Size of digest in octets */ | |
21 144, /* Input block size in octets */ | |
22 { 2,16,840,1,101,3,4,2,7 }, /* ASN.1 OID */ | |
23 9, /* Length OID */ | |
24 &sha3_224_init, | |
25 &sha3_process, | |
26 &sha3_done, | |
27 &sha3_224_test, | |
28 NULL | |
29 }; | |
30 | |
31 const struct ltc_hash_descriptor sha3_256_desc = | |
32 { | |
33 "sha3-256", /* name of hash */ | |
34 18, /* internal ID */ | |
35 32, /* Size of digest in octets */ | |
36 136, /* Input block size in octets */ | |
37 { 2,16,840,1,101,3,4,2,8 }, /* ASN.1 OID */ | |
38 9, /* Length OID */ | |
39 &sha3_256_init, | |
40 &sha3_process, | |
41 &sha3_done, | |
42 &sha3_256_test, | |
43 NULL | |
44 }; | |
45 | |
46 const struct ltc_hash_descriptor sha3_384_desc = | |
47 { | |
48 "sha3-384", /* name of hash */ | |
49 19, /* internal ID */ | |
50 48, /* Size of digest in octets */ | |
51 104, /* Input block size in octets */ | |
52 { 2,16,840,1,101,3,4,2,9 }, /* ASN.1 OID */ | |
53 9, /* Length OID */ | |
54 &sha3_384_init, | |
55 &sha3_process, | |
56 &sha3_done, | |
57 &sha3_384_test, | |
58 NULL | |
59 }; | |
60 | |
61 const struct ltc_hash_descriptor sha3_512_desc = | |
62 { | |
63 "sha3-512", /* name of hash */ | |
64 20, /* internal ID */ | |
65 64, /* Size of digest in octets */ | |
66 72, /* Input block size in octets */ | |
67 { 2,16,840,1,101,3,4,2,10 }, /* ASN.1 OID */ | |
68 9, /* Length OID */ | |
69 &sha3_512_init, | |
70 &sha3_process, | |
71 &sha3_done, | |
72 &sha3_512_test, | |
73 NULL | |
74 }; | |
75 | |
76 #define SHA3_KECCAK_SPONGE_WORDS 25 /* 1600 bits > 200 bytes > 25 x ulong64 */ | |
77 #define SHA3_KECCAK_ROUNDS 24 | |
78 | |
79 static const ulong64 keccakf_rndc[24] = { | |
80 CONST64(0x0000000000000001), CONST64(0x0000000000008082), | |
81 CONST64(0x800000000000808a), CONST64(0x8000000080008000), | |
82 CONST64(0x000000000000808b), CONST64(0x0000000080000001), | |
83 CONST64(0x8000000080008081), CONST64(0x8000000000008009), | |
84 CONST64(0x000000000000008a), CONST64(0x0000000000000088), | |
85 CONST64(0x0000000080008009), CONST64(0x000000008000000a), | |
86 CONST64(0x000000008000808b), CONST64(0x800000000000008b), | |
87 CONST64(0x8000000000008089), CONST64(0x8000000000008003), | |
88 CONST64(0x8000000000008002), CONST64(0x8000000000000080), | |
89 CONST64(0x000000000000800a), CONST64(0x800000008000000a), | |
90 CONST64(0x8000000080008081), CONST64(0x8000000000008080), | |
91 CONST64(0x0000000080000001), CONST64(0x8000000080008008) | |
92 }; | |
93 | |
94 static const unsigned keccakf_rotc[24] = { | |
95 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 | |
96 }; | |
97 | |
98 static const unsigned keccakf_piln[24] = { | |
99 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 | |
100 }; | |
101 | |
102 static void keccakf(ulong64 s[25]) | |
103 { | |
104 int i, j, round; | |
105 ulong64 t, bc[5]; | |
106 | |
107 for(round = 0; round < SHA3_KECCAK_ROUNDS; round++) { | |
108 /* Theta */ | |
109 for(i = 0; i < 5; i++) | |
110 bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; | |
111 | |
112 for(i = 0; i < 5; i++) { | |
113 t = bc[(i + 4) % 5] ^ ROL64(bc[(i + 1) % 5], 1); | |
114 for(j = 0; j < 25; j += 5) | |
115 s[j + i] ^= t; | |
116 } | |
117 /* Rho Pi */ | |
118 t = s[1]; | |
119 for(i = 0; i < 24; i++) { | |
120 j = keccakf_piln[i]; | |
121 bc[0] = s[j]; | |
122 s[j] = ROL64(t, keccakf_rotc[i]); | |
123 t = bc[0]; | |
124 } | |
125 /* Chi */ | |
126 for(j = 0; j < 25; j += 5) { | |
127 for(i = 0; i < 5; i++) | |
128 bc[i] = s[j + i]; | |
129 for(i = 0; i < 5; i++) | |
130 s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; | |
131 } | |
132 /* Iota */ | |
133 s[0] ^= keccakf_rndc[round]; | |
134 } | |
135 } | |
136 | |
137 /* Public Inteface */ | |
138 | |
139 int sha3_224_init(hash_state *md) | |
140 { | |
141 LTC_ARGCHK(md != NULL); | |
142 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
143 md->sha3.capacity_words = 2 * 224 / (8 * sizeof(ulong64)); | |
144 return CRYPT_OK; | |
145 } | |
146 | |
147 int sha3_256_init(hash_state *md) | |
148 { | |
149 LTC_ARGCHK(md != NULL); | |
150 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
151 md->sha3.capacity_words = 2 * 256 / (8 * sizeof(ulong64)); | |
152 return CRYPT_OK; | |
153 } | |
154 | |
155 int sha3_384_init(hash_state *md) | |
156 { | |
157 LTC_ARGCHK(md != NULL); | |
158 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
159 md->sha3.capacity_words = 2 * 384 / (8 * sizeof(ulong64)); | |
160 return CRYPT_OK; | |
161 } | |
162 | |
163 int sha3_512_init(hash_state *md) | |
164 { | |
165 LTC_ARGCHK(md != NULL); | |
166 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
167 md->sha3.capacity_words = 2 * 512 / (8 * sizeof(ulong64)); | |
168 return CRYPT_OK; | |
169 } | |
170 | |
171 int sha3_shake_init(hash_state *md, int num) | |
172 { | |
173 LTC_ARGCHK(md != NULL); | |
174 if (num != 128 && num != 256) return CRYPT_INVALID_ARG; | |
175 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
176 md->sha3.capacity_words = (unsigned short)(2 * num / (8 * sizeof(ulong64))); | |
177 return CRYPT_OK; | |
178 } | |
179 | |
180 int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen) | |
181 { | |
182 /* 0...7 -- how much is needed to have a word */ | |
183 unsigned old_tail = (8 - md->sha3.byte_index) & 7; | |
184 | |
185 unsigned long words; | |
186 unsigned tail; | |
187 unsigned long i; | |
188 | |
189 if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
190 LTC_ARGCHK(md != NULL); | |
191 LTC_ARGCHK(in != NULL); | |
192 | |
193 if(inlen < old_tail) { /* have no complete word or haven't started the word yet */ | |
194 while (inlen--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); | |
195 return CRYPT_OK; | |
196 } | |
197 | |
198 if(old_tail) { /* will have one word to process */ | |
199 inlen -= old_tail; | |
200 while (old_tail--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); | |
201 /* now ready to add saved to the sponge */ | |
202 md->sha3.s[md->sha3.word_index] ^= md->sha3.saved; | |
203 md->sha3.byte_index = 0; | |
204 md->sha3.saved = 0; | |
205 if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { | |
206 keccakf(md->sha3.s); | |
207 md->sha3.word_index = 0; | |
208 } | |
209 } | |
210 | |
211 /* now work in full words directly from input */ | |
212 words = inlen / sizeof(ulong64); | |
213 tail = inlen - words * sizeof(ulong64); | |
214 | |
215 for(i = 0; i < words; i++, in += sizeof(ulong64)) { | |
216 ulong64 t; | |
217 LOAD64L(t, in); | |
218 md->sha3.s[md->sha3.word_index] ^= t; | |
219 if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { | |
220 keccakf(md->sha3.s); | |
221 md->sha3.word_index = 0; | |
222 } | |
223 } | |
224 | |
225 /* finally, save the partial word */ | |
226 while (tail--) { | |
227 md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); | |
228 } | |
229 return CRYPT_OK; | |
230 } | |
231 | |
232 int sha3_done(hash_state *md, unsigned char *hash) | |
233 { | |
234 unsigned i; | |
235 | |
236 LTC_ARGCHK(md != NULL); | |
237 LTC_ARGCHK(hash != NULL); | |
238 | |
239 md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x06) << (md->sha3.byte_index * 8))); | |
240 md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); | |
241 keccakf(md->sha3.s); | |
242 | |
243 /* store sha3.s[] as little-endian bytes into sha3.sb */ | |
244 for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { | |
245 STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); | |
246 } | |
247 | |
248 XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4); | |
249 return CRYPT_OK; | |
250 } | |
251 | |
252 int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen) | |
253 { | |
254 /* IMPORTANT NOTE: sha3_shake_done can be called many times */ | |
255 unsigned long idx; | |
256 unsigned i; | |
257 | |
258 if (outlen == 0) return CRYPT_OK; /* nothing to do */ | |
259 LTC_ARGCHK(md != NULL); | |
260 LTC_ARGCHK(out != NULL); | |
261 | |
262 if (!md->sha3.xof_flag) { | |
263 /* shake_xof operation must be done only once */ | |
264 md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x1F) << (md->sha3.byte_index * 8))); | |
265 md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); | |
266 keccakf(md->sha3.s); | |
267 /* store sha3.s[] as little-endian bytes into sha3.sb */ | |
268 for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { | |
269 STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); | |
270 } | |
271 md->sha3.byte_index = 0; | |
272 md->sha3.xof_flag = 1; | |
273 } | |
274 | |
275 for (idx = 0; idx < outlen; idx++) { | |
276 if(md->sha3.byte_index >= (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words) * 8) { | |
277 keccakf(md->sha3.s); | |
278 /* store sha3.s[] as little-endian bytes into sha3.sb */ | |
279 for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { | |
280 STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); | |
281 } | |
282 md->sha3.byte_index = 0; | |
283 } | |
284 out[idx] = md->sha3.sb[md->sha3.byte_index++]; | |
285 } | |
286 return CRYPT_OK; | |
287 } | |
288 | |
289 int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) | |
290 { | |
291 hash_state md; | |
292 int err; | |
293 LTC_ARGCHK(in != NULL); | |
294 LTC_ARGCHK(out != NULL); | |
295 LTC_ARGCHK(outlen != NULL); | |
296 if ((err = sha3_shake_init(&md, num)) != CRYPT_OK) return err; | |
297 if ((err = sha3_shake_process(&md, in, inlen)) != CRYPT_OK) return err; | |
298 if ((err = sha3_shake_done(&md, out, *outlen)) != CRYPT_OK) return err; | |
299 return CRYPT_OK; | |
300 } | |
301 | |
302 #endif | |
303 | |
304 /* ref: $Format:%D$ */ | |
305 /* git commit: $Format:%H$ */ | |
306 /* commit time: $Format:%ai$ */ |