From: Niels Möller Date: Sun, 24 Mar 2024 13:10:23 +0000 (+0100) Subject: Generalize shake functions, and move to sha3-shake.c. X-Git-Tag: nettle_3.10rc1~19^2~5 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=bf161425e215ec3177f7f472b39fa858988f7e0a;p=thirdparty%2Fnettle.git Generalize shake functions, and move to sha3-shake.c. --- diff --git a/ChangeLog b/ChangeLog index b8a36979..e975efb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2024-03-24 Niels Möller + * sha3-shake.c (_nettle_sha3_shake, _nettle_sha3_shake_output): + New file, new functions. Generalizations of sha3_256_shake and + sha3_256_shake_output, respectively. + * shake256.c (sha3_256_shake, sha3_256_shake_output): Implement in + terms of calls to the new functions. + * Makefile.in (nettle_SOURCES): Add sha3-shake.c. + * sha3.c (_nettle_sha3_update): Use MD_FILL_OR_RETURN_INDEX. (sha3_xor_block): New function, taken out from sha3_absorb. (_nettle_sha3_pad): Call sha3_xor_block, not sha3_absorb. diff --git a/Makefile.in b/Makefile.in index f027e762..6953a528 100644 --- a/Makefile.in +++ b/Makefile.in @@ -151,7 +151,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \ sha3.c sha3-permute.c \ sha3-224.c sha3-224-meta.c sha3-256.c sha3-256-meta.c \ sha3-384.c sha3-384-meta.c sha3-512.c sha3-512-meta.c \ - shake256.c \ + sha3-shake.c shake256.c \ sm3.c sm3-meta.c \ serpent-set-key.c serpent-encrypt.c serpent-decrypt.c \ serpent-meta.c \ diff --git a/sha3-internal.h b/sha3-internal.h index 3778c6a5..669b9449 100644 --- a/sha3-internal.h +++ b/sha3-internal.h @@ -58,5 +58,16 @@ _nettle_sha3_pad (struct sha3_state *state, #define _sha3_pad_shake(state, block_size, block, pos) \ _nettle_sha3_pad (state, block_size, block, pos, SHA3_SHAKE_MAGIC) +void +_nettle_sha3_shake (struct sha3_state *state, + unsigned block_size, uint8_t *block, + unsigned index, + size_t length, uint8_t *dst); + +unsigned +_nettle_sha3_shake_output (struct sha3_state *state, + unsigned block_size, uint8_t *block, + unsigned index, + size_t length, uint8_t *dst); #endif diff --git a/sha3-shake.c b/sha3-shake.c new file mode 100644 index 00000000..d52d011d --- /dev/null +++ b/sha3-shake.c @@ -0,0 +1,118 @@ +/* sha3-shake.c + + Copyright (C) 2017, 2024 Daiki Ueno + Copyright (C) 2017 Red Hat, Inc. + Copyright (C) 2024 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle 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 copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "sha3.h" +#include "sha3-internal.h" + +#include "nettle-write.h" + +#define INDEX_HIGH_BIT (~((UINT_MAX) >> 1)) + +void +_nettle_sha3_shake (struct sha3_state *state, + unsigned block_size, uint8_t *block, + unsigned index, + size_t length, uint8_t *dst) +{ + _sha3_pad_shake (state, block_size, block, index); + + while (length > block_size) + { + sha3_permute (state); + _nettle_write_le64 (SHA3_256_BLOCK_SIZE, dst, state->a); + length -= block_size; + dst += block_size; + } + + sha3_permute (state); + _nettle_write_le64 (length, dst, state->a); +} + +unsigned +_nettle_sha3_shake_output (struct sha3_state *state, + unsigned block_size, uint8_t *block, + unsigned index, + size_t length, uint8_t *dst) +{ + unsigned left; + + /* We use the leftmost bit as a flag to indicate SHAKE is initialized. */ + if (index < block_size) + { + /* This is the first call of _shake_output. */ + _sha3_pad_shake (state, block_size, block, index); + /* Point at the end of block to trigger fill in of the buffer. */ + index = block_size; + } + else + index &= ~INDEX_HIGH_BIT; + + assert (index <= block_size); + + /* Write remaining data from the buffer. */ + left = block_size - index; + if (length <= left) + { + memcpy (dst, block + index, length); + return (index + length) | INDEX_HIGH_BIT; + } + else + { + memcpy (dst, block + index, left); + length -= left; + dst += left; + } + + /* Write full blocks. */ + while (length > block_size) + { + sha3_permute (state); + _nettle_write_le64 (block_size, dst, state->a); + length -= block_size; + dst += block_size; + } + + sha3_permute (state); + /* Fill in the buffer for next call. */ + _nettle_write_le64 (block_size, block, state->a); + memcpy (dst, block, length); + return length | INDEX_HIGH_BIT; +} diff --git a/shake256.c b/shake256.c index 1bc9eb08..721c6ae0 100644 --- a/shake256.c +++ b/shake256.c @@ -36,89 +36,23 @@ # include "config.h" #endif -#include -#include -#include -#include - #include "sha3.h" #include "sha3-internal.h" -#include "nettle-write.h" - -#define INDEX_HIGH_BIT (~((UINT_MAX) >> 1)) - void sha3_256_shake (struct sha3_256_ctx *ctx, - size_t length, - uint8_t *dst) + size_t length, uint8_t *dst) { - _sha3_pad_shake (&ctx->state, SHA3_256_BLOCK_SIZE, ctx->block, ctx->index); - while (length > SHA3_256_BLOCK_SIZE) - { - sha3_permute (&ctx->state); - _nettle_write_le64 (SHA3_256_BLOCK_SIZE, dst, ctx->state.a); - length -= SHA3_256_BLOCK_SIZE; - dst += SHA3_256_BLOCK_SIZE; - } - sha3_permute (&ctx->state); - _nettle_write_le64 (length, dst, ctx->state.a); - + _nettle_sha3_shake (&ctx->state, sizeof (ctx->block), ctx->block, ctx->index, length, dst); sha3_256_init (ctx); } void sha3_256_shake_output (struct sha3_256_ctx *ctx, - size_t length, - uint8_t *digest) + size_t length, uint8_t *digest) { - unsigned index, left; - - /* We use the leftmost bit as a flag to indicate SHAKE is initialized. */ - if (ctx->index & INDEX_HIGH_BIT) - index = ctx->index & ~INDEX_HIGH_BIT; - else - { - /* This is the first call of _shake_output. */ - _sha3_pad_shake (&ctx->state, sizeof (ctx->block), ctx->block, ctx->index); - /* Point at the end of block to trigger fill in of the buffer. */ - index = sizeof (ctx->block); - } - - assert (index <= sizeof (ctx->block)); - - /* Write remaining data from the buffer. */ - left = sizeof (ctx->block) - index; - if (length <= left) - { - memcpy (digest, ctx->block + index, length); - ctx->index = (index + length) | INDEX_HIGH_BIT; - return; - } - else - { - memcpy (digest, ctx->block + index, left); - length -= left; - digest += left; - } - - /* Write full blocks. */ - while (length > sizeof (ctx->block)) - { - sha3_permute (&ctx->state); - _nettle_write_le64 (sizeof (ctx->block), digest, ctx->state.a); - length -= sizeof (ctx->block); - digest += sizeof (ctx->block); - } - - if (length > 0) - { - /* Fill in the buffer for next call. */ - sha3_permute (&ctx->state); - _nettle_write_le64 (sizeof (ctx->block), ctx->block, ctx->state.a); - memcpy (digest, ctx->block, length); - ctx->index = length | INDEX_HIGH_BIT; - } - else - ctx->index = sizeof (ctx->block) | INDEX_HIGH_BIT; + ctx->index = + _nettle_sha3_shake_output (&ctx->state, + sizeof (ctx->block), ctx->block, ctx->index, + length, digest); }