]> pd.if.org Git - zpackage/blob - libtomcrypt/src/hashes/sha3.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / hashes / sha3.c
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$ */