Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/hashes/sha3.c
5971 views
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