X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/1047c205103e6da9fc6a317f41583147dbc11aa3..a1a6042e24c9873aa6abf668bcb68d39d0eb4190:/sha3.h diff --git a/sha3.h b/sha3.h new file mode 100644 index 0000000..a27a8be --- /dev/null +++ b/sha3.h @@ -0,0 +1,275 @@ +/* -*-c-*- + * + * The SHA3 algorithm family + * + * (c) 2017 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of secnet. + * See README for full list of copyright holders. + * + * secnet is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version d of the License, or + * (at your option) any later version. + * + * secnet is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 3 along with secnet; if not, see + * https://www.gnu.org/licenses/gpl.html. + * + * This file was originally part of Catacomb, but has been automatically + * modified for incorporation into secnet: see `import-catacomb-crypto' + * for details. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef CATACOMB_SHA3_H +#define CATACOMB_SHA3_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Notes on the SHA3 algorithm family --------------------------------* + * + * The winner of the SHA3 competition was Keccak, designed by Guido Bertoni, + * Joan Daemen, Michaël Peeters, and Gilles Van Assche. The algorithm uses + * their `sponge construction', based on a fixed attempt to instantiate an + * `ideal permutation'. The construction is rather versatile, and NIST has + * standardized a number of algorithms based on it. + * + * The basic offerings are the drop-in replacements for the SHA2 family. + * These are slower than is ideal, because of the decision to provide O(2^n) + * resistance to second-preimage attacks for the n-bit hash function, which + * means that, effectively, the capacity parameter is set unnecessarily + * large. (There was a major fuss when NIST tried to change this in a draft + * of te standard.) All of the obvious hash modes, e.g., HMAC, MGF, can be + * applied to the SHA3 hash functions, though I can't really recommend this: + * there's almost certainly a better way of doing whatever it is. + * + * Other members of the family are: SHAKE and cSHAKE, `extendable-output + * funnctions' which can be used directly in place of MGFs; and KMAC, a + * message authentication code with arbitrary-length key, message, and tag, + * which can therefore be used as a key-derivation function. The cSHAKE + * construction, on which KMAC is based, introduces a personalization string + * which can be used for domain separation. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "fake-mLib-bits.h" + +#ifndef CATACOMB_KECCAK1600_H +# include "keccak1600.h" +#endif + +/*----- The SHA3 hash function family -------------------------------------*/ + +typedef struct sha3_ctx { + keccak1600_state s; + unsigned r, w, n; + octet buf[200]; +} sha3_ctx; +#define sha3_224_ctx sha3_ctx +#define sha3_256_ctx sha3_ctx +#define sha3_384_ctx sha3_ctx +#define sha3_512_ctx sha3_ctx + +#define SHA3_224_HASHSZ 28 +#define SHA3_256_HASHSZ 32 +#define SHA3_384_HASHSZ 48 +#define SHA3_512_HASHSZ 64 + +#define SHA3_224_BUFSZ 144 +#define SHA3_256_BUFSZ 136 +#define SHA3_384_BUFSZ 104 +#define SHA3_512_BUFSZ 72 + +#define SHA3_STATESZ (sizeof(sha3_ctx)) +#define SHA3_224_STATESZ SHA3_STATESZ +#define SHA3_256_STATESZ SHA3_STATESZ +#define SHA3_384_STATESZ SHA3_STATESZ +#define SHA3_512_STATESZ SHA3_STATESZ + +/* --- @sha3_{224,256,384,512}_init@ --- * + * + * Arguments: @sha3_ctx *ctx@ = pointer to context block to initialize + * + * Returns: --- + * + * Use: Initializes a SHA3 hashing context for use. + */ + +extern void sha3_224_init(sha3_ctx */*ctx*/); +extern void sha3_256_init(sha3_ctx */*ctx*/); +extern void sha3_384_init(sha3_ctx */*ctx*/); +extern void sha3_512_init(sha3_ctx */*ctx*/); + +/* --- @sha3_hash@ --- * + * + * Arguments: @sha3_ctx *ctx@ = pointer to context bock + * @const void *p@ = pointer to data to hash + * @size_t sz@ = size of buffer to hash + * + * Returns: --- + * + * Use: Hashes a buffer of data. The buffer may be of any size and + * alignment. + */ + +#define sha3_224_hash sha3_hash +#define sha3_256_hash sha3_hash +#define sha3_384_hash sha3_hash +#define sha3_512_hash sha3_hash + +extern void sha3_hash(sha3_ctx */*ctx*/, const void */*p*/, size_t /*sz*/); + +/* --- @sha3_done@ --- * + * + * Arguments: @sha3_ctx *ctx@ = pointer to context block + * @void *hash@ = pointer to output buffer + * + * Returns: --- + * + * Use: Returns the hash of the data read so far. + */ + +#define sha3_224_done sha3_done +#define sha3_256_done sha3_done +#define sha3_384_done sha3_done +#define sha3_512_done sha3_done + +extern void sha3_done(sha3_ctx */*ctx*/, void */*hash*/); + +/*----- The cSHAKE XOF algorithm ------------------------------------------*/ + +typedef struct shake_ctx { + sha3_ctx h; + unsigned st, op; +} shake_ctx; +#define shake128_ctx shake_ctx +#define shake256_ctx shake_ctx + +#define SHAKE128_KEYSZ 16 +#define SHAKE256_KEYSZ 32 + +#define SHAKE128_HASHSZ 32 /* Somewhat arbitrary... */ +#define SHAKE256_HASHSZ 64 + +/* --- @cshake{128,256}_init@ --- * + * + * Arguments: @shake_ctx *ctx@ = pointer to context to initialize + * @const void *func@ = NIST-allocated function name + * @size_t fsz@ = length of function name + * @const void *perso@ = user personalization string + * @size_t psz@ = length of personalization string + * + * Returns: --- + * + * Use: Initializes a cSHAKE context. The context is initially in + * the `absorbing' state: feed it data with @shake_hash@. + */ + +extern void cshake128_init(shake_ctx */*ctx*/, + const void */*func*/, size_t /*fsz*/, + const void */*perso*/, size_t /*psz*/); + +extern void cshake256_init(shake_ctx */*ctx*/, + const void */*func*/, size_t /*fsz*/, + const void */*perso*/, size_t /*psz*/); + +/* --- @shake{128,256}_init@ --- * + * + * Arguments: @sha3_ctx *ctx@ = pointer to context to initialize + * + * Returns: --- + * + * Use: Initializes a SHAKE context. The context is initially in + * the `absorbing' state: feed it data with @shake_hash@. + */ + +extern void shake128_init(shake_ctx */*ctx*/); +extern void shake256_init(shake_ctx */*ctx*/); + +/* --- @shake_hash@ --- * + * + * Arguments: @shake_ctx *ctx@ = context to update + * @const void *p@ = input buffer + * @size_t sz@ = size of input + * + * Returns: --- + * + * Use: Feeds input data into a SHAKE context. The context must be + * in `absorbing' state. + */ + +extern void shake_hash(shake_ctx */*ctx*/, const void */*p*/, size_t /*sz*/); + +/* --- @shake_xof@ --- * + * + * Arguments: @shake_ctx *ctx@ = context to update + * + * Returns: --- + * + * Use: Switches the context into `squeezing' state. Use @shake_get@ + * or @shake_mask@ to extract data. + */ + +extern void shake_xof(shake_ctx */*ctx*/); + +/* --- @shake_get@ --- * + * + * Arguments: @shake_ctx *ctx@ = context to update + * @void *p@ = output buffer + * @size_t sz@ = size of output + * + * Returns: --- + * + * Use: Extracts output from a SHAKE context. The context must be + * in `squeezing' state. + */ + +extern void shake_get(shake_ctx */*ctx*/, void */*p*/, size_t /*sz*/); + +/* --- @shake_done@ --- * + * + * Arguments: @shake_ctx *ctx@ = context to update + * @void *h@ = where to write the hash + * @size_t hsz@ = size of the hash to make + * + * Returns: --- + * + * Use: Switches the context into `squeezing' state. Use @shake_get@ + * or @shake_mask@ to extract data. + */ + +extern void shake_done(shake_ctx */*ctx*/, void */*h*/, size_t /*hsz*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif