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