1 // SPDX-License-Identifier: BSD-2-Clause 2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 3 * 4 * LibTomCrypt is a library that provides various cryptographic 5 * algorithms in a highly modular and flexible manner. 6 * 7 * The library is free for all purposes without any express 8 * guarantee it works. 9 */ 10 11 /* based on https://github.com/brainhub/SHA3IUF (public domain) */ 12 13 #include "tomcrypt_private.h" 14 15 #ifdef LTC_SHA3 16 17 const struct ltc_hash_descriptor sha3_224_desc = 18 { 19 "sha3-224", /* name of hash */ 20 17, /* internal ID */ 21 28, /* Size of digest in octets */ 22 144, /* Input block size in octets */ 23 { 2,16,840,1,101,3,4,2,7 }, /* ASN.1 OID */ 24 9, /* Length OID */ 25 &sha3_224_init, 26 &sha3_process, 27 &sha3_done, 28 &sha3_224_test, 29 NULL 30 }; 31 32 const struct ltc_hash_descriptor sha3_256_desc = 33 { 34 "sha3-256", /* name of hash */ 35 18, /* internal ID */ 36 32, /* Size of digest in octets */ 37 136, /* Input block size in octets */ 38 { 2,16,840,1,101,3,4,2,8 }, /* ASN.1 OID */ 39 9, /* Length OID */ 40 &sha3_256_init, 41 &sha3_process, 42 &sha3_done, 43 &sha3_256_test, 44 NULL 45 }; 46 47 const struct ltc_hash_descriptor sha3_384_desc = 48 { 49 "sha3-384", /* name of hash */ 50 19, /* internal ID */ 51 48, /* Size of digest in octets */ 52 104, /* Input block size in octets */ 53 { 2,16,840,1,101,3,4,2,9 }, /* ASN.1 OID */ 54 9, /* Length OID */ 55 &sha3_384_init, 56 &sha3_process, 57 &sha3_done, 58 &sha3_384_test, 59 NULL 60 }; 61 62 const struct ltc_hash_descriptor sha3_512_desc = 63 { 64 "sha3-512", /* name of hash */ 65 20, /* internal ID */ 66 64, /* Size of digest in octets */ 67 72, /* Input block size in octets */ 68 { 2,16,840,1,101,3,4,2,10 }, /* ASN.1 OID */ 69 9, /* Length OID */ 70 &sha3_512_init, 71 &sha3_process, 72 &sha3_done, 73 &sha3_512_test, 74 NULL 75 }; 76 #endif 77 78 #ifdef LTC_KECCAK 79 const struct ltc_hash_descriptor keccak_224_desc = 80 { 81 "keccak224", /* name of hash */ 82 29, /* internal ID */ 83 28, /* Size of digest in octets */ 84 144, /* Input block size in octets */ 85 { 0 }, 0, /* no ASN.1 OID */ 86 &sha3_224_init, 87 &sha3_process, 88 &keccak_done, 89 &keccak_224_test, 90 NULL 91 }; 92 93 const struct ltc_hash_descriptor keccak_256_desc = 94 { 95 "keccak256", /* name of hash */ 96 30, /* internal ID */ 97 32, /* Size of digest in octets */ 98 136, /* Input block size in octets */ 99 { 0 }, 0, /* no ASN.1 OID */ 100 &sha3_256_init, 101 &sha3_process, 102 &keccak_done, 103 &keccak_256_test, 104 NULL 105 }; 106 107 const struct ltc_hash_descriptor keccak_384_desc = 108 { 109 "keccak384", /* name of hash */ 110 31, /* internal ID */ 111 48, /* Size of digest in octets */ 112 104, /* Input block size in octets */ 113 { 0 }, 0, /* no ASN.1 OID */ 114 &sha3_384_init, 115 &sha3_process, 116 &keccak_done, 117 &keccak_384_test, 118 NULL 119 }; 120 121 const struct ltc_hash_descriptor keccak_512_desc = 122 { 123 "keccak512", /* name of hash */ 124 32, /* internal ID */ 125 64, /* Size of digest in octets */ 126 72, /* Input block size in octets */ 127 { 0 }, 0, /* no ASN.1 OID */ 128 &sha3_512_init, 129 &sha3_process, 130 &keccak_done, 131 &keccak_512_test, 132 NULL 133 }; 134 #endif 135 136 #if defined(LTC_SHA3) || defined(LTC_KECCAK) 137 138 #define SHA3_KECCAK_SPONGE_WORDS 25 /* 1600 bits > 200 bytes > 25 x ulong64 */ 139 #define SHA3_KECCAK_ROUNDS 24 140 141 static const ulong64 keccakf_rndc[24] = { 142 CONST64(0x0000000000000001), CONST64(0x0000000000008082), 143 CONST64(0x800000000000808a), CONST64(0x8000000080008000), 144 CONST64(0x000000000000808b), CONST64(0x0000000080000001), 145 CONST64(0x8000000080008081), CONST64(0x8000000000008009), 146 CONST64(0x000000000000008a), CONST64(0x0000000000000088), 147 CONST64(0x0000000080008009), CONST64(0x000000008000000a), 148 CONST64(0x000000008000808b), CONST64(0x800000000000008b), 149 CONST64(0x8000000000008089), CONST64(0x8000000000008003), 150 CONST64(0x8000000000008002), CONST64(0x8000000000000080), 151 CONST64(0x000000000000800a), CONST64(0x800000008000000a), 152 CONST64(0x8000000080008081), CONST64(0x8000000000008080), 153 CONST64(0x0000000080000001), CONST64(0x8000000080008008) 154 }; 155 156 static const unsigned keccakf_rotc[24] = { 157 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 158 }; 159 160 static const unsigned keccakf_piln[24] = { 161 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 162 }; 163 164 static void keccakf(ulong64 s[25]) 165 { 166 int i, j, round; 167 ulong64 t, bc[5]; 168 169 for(round = 0; round < SHA3_KECCAK_ROUNDS; round++) { 170 /* Theta */ 171 for(i = 0; i < 5; i++) { 172 bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; 173 } 174 for(i = 0; i < 5; i++) { 175 t = bc[(i + 4) % 5] ^ ROL64(bc[(i + 1) % 5], 1); 176 for(j = 0; j < 25; j += 5) { 177 s[j + i] ^= t; 178 } 179 } 180 /* Rho Pi */ 181 t = s[1]; 182 for(i = 0; i < 24; i++) { 183 j = keccakf_piln[i]; 184 bc[0] = s[j]; 185 s[j] = ROL64(t, keccakf_rotc[i]); 186 t = bc[0]; 187 } 188 /* Chi */ 189 for(j = 0; j < 25; j += 5) { 190 for(i = 0; i < 5; i++) { 191 bc[i] = s[j + i]; 192 } 193 for(i = 0; i < 5; i++) { 194 s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; 195 } 196 } 197 /* Iota */ 198 s[0] ^= keccakf_rndc[round]; 199 } 200 } 201 202 static LTC_INLINE int _done(hash_state *md, unsigned char *hash, ulong64 pad) 203 { 204 unsigned i; 205 206 LTC_ARGCHK(md != NULL); 207 LTC_ARGCHK(hash != NULL); 208 209 md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (pad << (md->sha3.byte_index * 8))); 210 md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); 211 keccakf(md->sha3.s); 212 213 /* store sha3.s[] as little-endian bytes into sha3.sb */ 214 for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { 215 STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); 216 } 217 218 XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4); 219 return CRYPT_OK; 220 } 221 222 /* Public Inteface */ 223 224 int sha3_224_init(hash_state *md) 225 { 226 LTC_ARGCHK(md != NULL); 227 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); 228 md->sha3.capacity_words = 2 * 224 / (8 * sizeof(ulong64)); 229 return CRYPT_OK; 230 } 231 232 int sha3_256_init(hash_state *md) 233 { 234 LTC_ARGCHK(md != NULL); 235 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); 236 md->sha3.capacity_words = 2 * 256 / (8 * sizeof(ulong64)); 237 return CRYPT_OK; 238 } 239 240 int sha3_384_init(hash_state *md) 241 { 242 LTC_ARGCHK(md != NULL); 243 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); 244 md->sha3.capacity_words = 2 * 384 / (8 * sizeof(ulong64)); 245 return CRYPT_OK; 246 } 247 248 int sha3_512_init(hash_state *md) 249 { 250 LTC_ARGCHK(md != NULL); 251 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); 252 md->sha3.capacity_words = 2 * 512 / (8 * sizeof(ulong64)); 253 return CRYPT_OK; 254 } 255 256 #ifdef LTC_SHA3 257 int sha3_shake_init(hash_state *md, int num) 258 { 259 LTC_ARGCHK(md != NULL); 260 if (num != 128 && num != 256) return CRYPT_INVALID_ARG; 261 XMEMSET(&md->sha3, 0, sizeof(md->sha3)); 262 md->sha3.capacity_words = (unsigned short)(2 * num / (8 * sizeof(ulong64))); 263 return CRYPT_OK; 264 } 265 #endif 266 267 int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen) 268 { 269 /* 0...7 -- how much is needed to have a word */ 270 unsigned old_tail = (8 - md->sha3.byte_index) & 7; 271 272 unsigned long words; 273 unsigned tail; 274 unsigned long i; 275 276 if (inlen == 0) return CRYPT_OK; /* nothing to do */ 277 LTC_ARGCHK(md != NULL); 278 LTC_ARGCHK(in != NULL); 279 280 if(inlen < old_tail) { /* have no complete word or haven't started the word yet */ 281 while (inlen--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); 282 return CRYPT_OK; 283 } 284 285 if(old_tail) { /* will have one word to process */ 286 inlen -= old_tail; 287 while (old_tail--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); 288 /* now ready to add saved to the sponge */ 289 md->sha3.s[md->sha3.word_index] ^= md->sha3.saved; 290 md->sha3.byte_index = 0; 291 md->sha3.saved = 0; 292 if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { 293 keccakf(md->sha3.s); 294 md->sha3.word_index = 0; 295 } 296 } 297 298 /* now work in full words directly from input */ 299 words = inlen / sizeof(ulong64); 300 tail = inlen - words * sizeof(ulong64); 301 302 for(i = 0; i < words; i++, in += sizeof(ulong64)) { 303 ulong64 t; 304 LOAD64L(t, in); 305 md->sha3.s[md->sha3.word_index] ^= t; 306 if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { 307 keccakf(md->sha3.s); 308 md->sha3.word_index = 0; 309 } 310 } 311 312 /* finally, save the partial word */ 313 while (tail--) { 314 md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); 315 } 316 return CRYPT_OK; 317 } 318 319 #ifdef LTC_SHA3 320 int sha3_done(hash_state *md, unsigned char *out) 321 { 322 return _done(md, out, CONST64(0x06)); 323 } 324 #endif 325 326 #ifdef LTC_KECCAK 327 int keccak_done(hash_state *md, unsigned char *out) 328 { 329 return _done(md, out, CONST64(0x01)); 330 } 331 #endif 332 333 #ifdef LTC_SHA3 334 int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen) 335 { 336 /* IMPORTANT NOTE: sha3_shake_done can be called many times */ 337 unsigned long idx; 338 unsigned i; 339 340 if (outlen == 0) return CRYPT_OK; /* nothing to do */ 341 LTC_ARGCHK(md != NULL); 342 LTC_ARGCHK(out != NULL); 343 344 if (!md->sha3.xof_flag) { 345 /* shake_xof operation must be done only once */ 346 md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x1F) << (md->sha3.byte_index * 8))); 347 md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); 348 keccakf(md->sha3.s); 349 /* store sha3.s[] as little-endian bytes into sha3.sb */ 350 for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { 351 STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); 352 } 353 md->sha3.byte_index = 0; 354 md->sha3.xof_flag = 1; 355 } 356 357 for (idx = 0; idx < outlen; idx++) { 358 if(md->sha3.byte_index >= (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words) * 8) { 359 keccakf(md->sha3.s); 360 /* store sha3.s[] as little-endian bytes into sha3.sb */ 361 for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { 362 STORE64L(md->sha3.s[i], md->sha3.sb + i * 8); 363 } 364 md->sha3.byte_index = 0; 365 } 366 out[idx] = md->sha3.sb[md->sha3.byte_index++]; 367 } 368 return CRYPT_OK; 369 } 370 371 int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, const unsigned long *outlen) 372 { 373 hash_state md; 374 int err; 375 LTC_ARGCHK(in != NULL); 376 LTC_ARGCHK(out != NULL); 377 LTC_ARGCHK(outlen != NULL); 378 if ((err = sha3_shake_init(&md, num)) != CRYPT_OK) return err; 379 if ((err = sha3_shake_process(&md, in, inlen)) != CRYPT_OK) return err; 380 if ((err = sha3_shake_done(&md, out, *outlen)) != CRYPT_OK) return err; 381 return CRYPT_OK; 382 } 383 #endif 384 385 #endif 386 387 /* ref: $Format:%D$ */ 388 /* git commit: $Format:%H$ */ 389 /* commit time: $Format:%ai$ */ 390