1*45e2a6c1Sjsing /* $OpenBSD: sha3.c,v 1.16 2024/11/23 15:38:12 jsing Exp $ */ 29bb5e18bSjsing /* 39bb5e18bSjsing * The MIT License (MIT) 49bb5e18bSjsing * 59bb5e18bSjsing * Copyright (c) 2015 Markku-Juhani O. Saarinen 69bb5e18bSjsing * 79bb5e18bSjsing * Permission is hereby granted, free of charge, to any person obtaining a copy 89bb5e18bSjsing * of this software and associated documentation files (the "Software"), to deal 99bb5e18bSjsing * in the Software without restriction, including without limitation the rights 109bb5e18bSjsing * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 119bb5e18bSjsing * copies of the Software, and to permit persons to whom the Software is 129bb5e18bSjsing * furnished to do so, subject to the following conditions: 139bb5e18bSjsing * 149bb5e18bSjsing * The above copyright notice and this permission notice shall be included in all 159bb5e18bSjsing * copies or substantial portions of the Software. 169bb5e18bSjsing * 179bb5e18bSjsing * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 189bb5e18bSjsing * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 199bb5e18bSjsing * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 209bb5e18bSjsing * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 219bb5e18bSjsing * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 229bb5e18bSjsing * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 239bb5e18bSjsing * SOFTWARE. 249bb5e18bSjsing */ 259bb5e18bSjsing 26ac5713a6Sjsing #include <endian.h> 270d9460fdSjsing #include <string.h> 28ac5713a6Sjsing 29c0cd1c8bSjsing #include "sha3_internal.h" 30e70bbf9bSjsing 31d44d5087Sjsing #define KECCAKF_ROUNDS 24 32d44d5087Sjsing 33d44d5087Sjsing #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 34d44d5087Sjsing 355c0ae387Sjsing static const uint64_t sha3_keccakf_rndc[24] = { 36e70bbf9bSjsing 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 37e70bbf9bSjsing 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, 38e70bbf9bSjsing 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 39e70bbf9bSjsing 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, 40e70bbf9bSjsing 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 41e70bbf9bSjsing 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 42e70bbf9bSjsing 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, 43e70bbf9bSjsing 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 44e70bbf9bSjsing }; 455c0ae387Sjsing static const int sha3_keccakf_rotc[24] = { 46e70bbf9bSjsing 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 47e70bbf9bSjsing 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 48e70bbf9bSjsing }; 495c0ae387Sjsing static const int sha3_keccakf_piln[24] = { 50e70bbf9bSjsing 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 51e70bbf9bSjsing 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 52e70bbf9bSjsing }; 53e70bbf9bSjsing 548e11058eSjsing static void 555c0ae387Sjsing sha3_keccakf(uint64_t st[25]) 565c0ae387Sjsing { 57e70bbf9bSjsing uint64_t t, bc[5]; 585c0ae387Sjsing int i, j, r; 59e70bbf9bSjsing 60*45e2a6c1Sjsing for (i = 0; i < 25; i++) 61*45e2a6c1Sjsing st[i] = le64toh(st[i]); 62e70bbf9bSjsing 63e70bbf9bSjsing for (r = 0; r < KECCAKF_ROUNDS; r++) { 64e70bbf9bSjsing 65e967e4e7Sjsing /* Theta */ 66e70bbf9bSjsing for (i = 0; i < 5; i++) 67e70bbf9bSjsing bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; 68e70bbf9bSjsing 69e70bbf9bSjsing for (i = 0; i < 5; i++) { 70e70bbf9bSjsing t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); 71e70bbf9bSjsing for (j = 0; j < 25; j += 5) 72e70bbf9bSjsing st[j + i] ^= t; 73e70bbf9bSjsing } 74e70bbf9bSjsing 75e967e4e7Sjsing /* Rho Pi */ 76e70bbf9bSjsing t = st[1]; 77e70bbf9bSjsing for (i = 0; i < 24; i++) { 785c0ae387Sjsing j = sha3_keccakf_piln[i]; 79e70bbf9bSjsing bc[0] = st[j]; 805c0ae387Sjsing st[j] = ROTL64(t, sha3_keccakf_rotc[i]); 81e70bbf9bSjsing t = bc[0]; 82e70bbf9bSjsing } 83e70bbf9bSjsing 84e967e4e7Sjsing /* Chi */ 85e70bbf9bSjsing for (j = 0; j < 25; j += 5) { 86e70bbf9bSjsing for (i = 0; i < 5; i++) 87e70bbf9bSjsing bc[i] = st[j + i]; 88e70bbf9bSjsing for (i = 0; i < 5; i++) 89e70bbf9bSjsing st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; 90e70bbf9bSjsing } 91e70bbf9bSjsing 92e967e4e7Sjsing /* Iota */ 935c0ae387Sjsing st[0] ^= sha3_keccakf_rndc[r]; 94e70bbf9bSjsing } 95e70bbf9bSjsing 96*45e2a6c1Sjsing for (i = 0; i < 25; i++) 97*45e2a6c1Sjsing st[i] = htole64(st[i]); 98e70bbf9bSjsing } 99e70bbf9bSjsing 1008a4ba2fcSjsing int 101f1b36196Sjsing sha3_init(sha3_ctx *c, int mdlen) 102e70bbf9bSjsing { 103aae7803dSjsing if (mdlen < 0 || mdlen >= KECCAK_BYTE_WIDTH / 2) 104aae7803dSjsing return 0; 105aae7803dSjsing 1060d9460fdSjsing memset(c, 0, sizeof(*c)); 107e70bbf9bSjsing 108e70bbf9bSjsing c->mdlen = mdlen; 109aae7803dSjsing c->rsize = KECCAK_BYTE_WIDTH - 2 * mdlen; 110e70bbf9bSjsing 111e70bbf9bSjsing return 1; 112e70bbf9bSjsing } 113e70bbf9bSjsing 1148a4ba2fcSjsing int 115f1b36196Sjsing sha3_update(sha3_ctx *c, const void *data, size_t len) 116e70bbf9bSjsing { 117acc18af8Sjsing size_t i, j; 118e70bbf9bSjsing 119e70bbf9bSjsing j = c->pt; 120e70bbf9bSjsing for (i = 0; i < len; i++) { 121ee266ad5Sjsing c->state.b[j++] ^= ((const uint8_t *) data)[i]; 122acc18af8Sjsing if (j >= c->rsize) { 123ee266ad5Sjsing sha3_keccakf(c->state.q); 124e70bbf9bSjsing j = 0; 125e70bbf9bSjsing } 126e70bbf9bSjsing } 127e70bbf9bSjsing c->pt = j; 128e70bbf9bSjsing 129e70bbf9bSjsing return 1; 130e70bbf9bSjsing } 131e70bbf9bSjsing 1328a4ba2fcSjsing int 133f1b36196Sjsing sha3_final(void *md, sha3_ctx *c) 134e70bbf9bSjsing { 135e70bbf9bSjsing int i; 136e70bbf9bSjsing 137ee266ad5Sjsing c->state.b[c->pt] ^= 0x06; 138acc18af8Sjsing c->state.b[c->rsize - 1] ^= 0x80; 139ee266ad5Sjsing sha3_keccakf(c->state.q); 140e70bbf9bSjsing 141e70bbf9bSjsing for (i = 0; i < c->mdlen; i++) { 142ee266ad5Sjsing ((uint8_t *) md)[i] = c->state.b[i]; 143e70bbf9bSjsing } 144e70bbf9bSjsing 145e70bbf9bSjsing return 1; 146e70bbf9bSjsing } 147e70bbf9bSjsing 148e967e4e7Sjsing /* SHAKE128 and SHAKE256 extensible-output functionality. */ 1498a4ba2fcSjsing void 150f1b36196Sjsing shake_xof(sha3_ctx *c) 151e70bbf9bSjsing { 152ee266ad5Sjsing c->state.b[c->pt] ^= 0x1F; 153acc18af8Sjsing c->state.b[c->rsize - 1] ^= 0x80; 154ee266ad5Sjsing sha3_keccakf(c->state.q); 155e70bbf9bSjsing c->pt = 0; 156e70bbf9bSjsing } 157e70bbf9bSjsing 1588a4ba2fcSjsing void 159f1b36196Sjsing shake_out(sha3_ctx *c, void *out, size_t len) 160e70bbf9bSjsing { 161acc18af8Sjsing size_t i, j; 162e70bbf9bSjsing 163e70bbf9bSjsing j = c->pt; 164e70bbf9bSjsing for (i = 0; i < len; i++) { 165acc18af8Sjsing if (j >= c->rsize) { 166ee266ad5Sjsing sha3_keccakf(c->state.q); 167e70bbf9bSjsing j = 0; 168e70bbf9bSjsing } 169ee266ad5Sjsing ((uint8_t *) out)[i] = c->state.b[j++]; 170e70bbf9bSjsing } 171e70bbf9bSjsing c->pt = j; 172e70bbf9bSjsing } 173