2024-03-24 Niels Möller <nisse@lysator.liu.se>
+ * 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.
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 \
#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
--- /dev/null
+/* 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 <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#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;
+}
# include "config.h"
#endif
-#include <assert.h>
-#include <limits.h>
-#include <stddef.h>
-#include <string.h>
-
#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);
}