/* * SHA3 implementation. * * Copyright (c) 2014 Marko Kreen * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #define PAD_SHA3 0x06 #define PAD_SHAKE 0x1f void sha3_224_reset(struct SHA3Context *ctx) { keccak_init(&ctx->kctx, SHA3_224_CAPACITY); ctx->padded = 0; ctx->obytes = SHA3_224_DIGEST_LENGTH; ctx->pad = PAD_SHA3; } void sha3_256_reset(struct SHA3Context *ctx) { keccak_init(&ctx->kctx, SHA3_256_CAPACITY); ctx->padded = 0; ctx->obytes = SHA3_256_DIGEST_LENGTH; ctx->pad = PAD_SHA3; } void sha3_384_reset(struct SHA3Context *ctx) { keccak_init(&ctx->kctx, SHA3_384_CAPACITY); ctx->padded = 0; ctx->obytes = SHA3_384_DIGEST_LENGTH; ctx->pad = PAD_SHA3; } void sha3_512_reset(struct SHA3Context *ctx) { keccak_init(&ctx->kctx, SHA3_512_CAPACITY); ctx->padded = 0; ctx->obytes = SHA3_512_DIGEST_LENGTH; ctx->pad = PAD_SHA3; } void shake128_reset(struct SHA3Context *ctx) { keccak_init(&ctx->kctx, SHAKE128_CAPACITY); ctx->padded = 0; ctx->obytes = SHAKE128_DIGEST_LENGTH; ctx->pad = PAD_SHAKE; } void shake256_reset(struct SHA3Context *ctx) { keccak_init(&ctx->kctx, SHAKE256_CAPACITY); ctx->padded = 0; ctx->obytes = SHAKE256_DIGEST_LENGTH; ctx->pad = PAD_SHAKE; } void sha3_update(struct SHA3Context *ctx, const void *ptr, unsigned len) { keccak_absorb(&ctx->kctx, ptr, len); } void sha3_final(struct SHA3Context *ctx, void *dst) { if (!ctx->padded) { keccak_pad(&ctx->kctx, &ctx->pad, 1); ctx->padded = 1; } keccak_squeeze(&ctx->kctx, dst, ctx->obytes); } void shake_update(struct SHA3Context *ctx, const void *ptr, unsigned len) { keccak_absorb(&ctx->kctx, ptr, len); } void shake_extract(struct SHA3Context *ctx, void *dst, unsigned count) { if (!ctx->padded) { keccak_pad(&ctx->kctx, &ctx->pad, 1); ctx->padded = 1; } keccak_squeeze(&ctx->kctx, dst, count); } /* * DigestInfo */ static const struct DigestInfo sha3_224_info = { (DigestInitFunc *)sha3_224_reset, (DigestUpdateFunc *)sha3_update, (DigestFinalFunc *)sha3_final, sizeof(struct SHA3Context), SHA3_224_DIGEST_LENGTH, SHA3_224_BLOCK_SIZE }; static const struct DigestInfo sha3_256_info = { (DigestInitFunc *)sha3_256_reset, (DigestUpdateFunc *)sha3_update, (DigestFinalFunc *)sha3_final, sizeof(struct SHA3Context), SHA3_256_DIGEST_LENGTH, SHA3_256_BLOCK_SIZE }; static const struct DigestInfo sha3_384_info = { (DigestInitFunc *)sha3_384_reset, (DigestUpdateFunc *)sha3_update, (DigestFinalFunc *)sha3_final, sizeof(struct SHA3Context), SHA3_384_DIGEST_LENGTH, SHA3_384_BLOCK_SIZE }; static const struct DigestInfo sha3_512_info = { (DigestInitFunc *)sha3_512_reset, (DigestUpdateFunc *)sha3_update, (DigestFinalFunc *)sha3_final, sizeof(struct SHA3Context), SHA3_512_DIGEST_LENGTH, SHA3_512_BLOCK_SIZE }; static const struct DigestInfo shake128_info = { (DigestInitFunc *)shake128_reset, (DigestUpdateFunc *)sha3_update, (DigestFinalFunc *)sha3_final, sizeof(struct SHA3Context), SHAKE128_DIGEST_LENGTH, SHAKE128_BLOCK_SIZE }; static const struct DigestInfo shake256_info = { (DigestInitFunc *)shake256_reset, (DigestUpdateFunc *)sha3_update, (DigestFinalFunc *)sha3_final, sizeof(struct SHA3Context), SHAKE256_DIGEST_LENGTH, SHAKE256_BLOCK_SIZE }; const struct DigestInfo *digest_SHA3_224(void) { return &sha3_224_info; } const struct DigestInfo *digest_SHA3_256(void) { return &sha3_256_info; } const struct DigestInfo *digest_SHA3_384(void) { return &sha3_384_info; } const struct DigestInfo *digest_SHA3_512(void) { return &sha3_512_info; } const struct DigestInfo *digest_SHAKE128(void) { return &shake128_info; } const struct DigestInfo *digest_SHAKE256(void) { return &shake256_info; }