From 1dc19a0714d3e58b9fbbe1838137002254ba87c1 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Sat, 23 Mar 2024 17:58:21 +0900
Subject: [PATCH 2/3] shake256: Rename sha3_256_shake_output to
 sha3_shake256_output

This adds a new family of functions to deal with SHAKE256.  The
original sha3_256_shake is deprecated in favor of this, and
re-implemented using the new functions.

Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
 sha3.h                    | 36 ++++++++++++++++++++++++++---------
 shake256.c                | 40 +++++++++++++++++++++++----------------
 testsuite/shake256-test.c | 10 +++++-----
 3 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/sha3.h b/sha3.h
index 4b7e186c..87cbb879 100644
--- a/sha3.h
+++ b/sha3.h
@@ -49,7 +49,9 @@ extern "C" {
 #define sha3_256_update nettle_sha3_256_update
 #define sha3_256_digest nettle_sha3_256_digest
 #define sha3_256_shake nettle_sha3_256_shake
-#define sha3_256_shake_output nettle_sha3_256_shake_output
+#define sha3_shake256_init nettle_sha3_shake256_init
+#define sha3_shake256_update nettle_sha3_shake256_update
+#define sha3_shake256_output nettle_sha3_shake256_output
 #define sha3_384_init nettle_sha3_384_init
 #define sha3_384_update nettle_sha3_384_update
 #define sha3_384_digest nettle_sha3_384_digest
@@ -91,6 +93,8 @@ sha3_permute (struct sha3_state *state);
 #define SHA3_512_DIGEST_SIZE 64
 #define SHA3_512_BLOCK_SIZE 72
 
+#define SHA3_SHAKE256_BLOCK_SIZE SHA3_256_BLOCK_SIZE
+
 /* For backwards compatibility */
 #define SHA3_224_DATA_SIZE SHA3_224_BLOCK_SIZE
 #define SHA3_256_DATA_SIZE SHA3_256_BLOCK_SIZE
@@ -137,17 +141,31 @@ sha3_256_digest(struct sha3_256_ctx *ctx,
 		size_t length,
 		uint8_t *digest);
 
-/* Alternative digest function implementing shake256, with arbitrary
-   digest size */
+/* This function is deprecated; consider migrating to sha3_shake256_*
+   interface.  */
 void
-sha3_256_shake(struct sha3_256_ctx *ctx,
-	       size_t length,
-	       uint8_t *digest);
+sha3_256_shake (struct sha3_256_ctx *ctx,
+		size_t length,
+		uint8_t *digest);
+
+/* Alternative interface implementing SHAKE256, with arbitrary digest size.  */
+struct sha3_shake256_ctx
+{
+  struct sha3_state state;
+  unsigned index;
+  uint8_t block[SHA3_SHAKE256_BLOCK_SIZE];
+};
+
+void
+sha3_shake256_init (struct sha3_shake256_ctx *ctx);
+
+void
+sha3_shake256_update (struct sha3_shake256_ctx *ctx,
+		      size_t length,
+		      const uint8_t *data);
 
-/* Unlike sha3_256_shake, this function can be called multiple times
-   to retrieve output from shake256 in an incremental manner */
 void
-sha3_256_shake_output(struct sha3_256_ctx *ctx,
+sha3_shake256_output (struct sha3_shake256_ctx *ctx,
 		      size_t length,
 		      uint8_t *digest);
 
diff --git a/shake256.c b/shake256.c
index 11d34d5e..879c0935 100644
--- a/shake256.c
+++ b/shake256.c
@@ -49,27 +49,25 @@
 #define INDEX_HIGH_BIT (~((UINT_MAX) >> 1))
 
 void
-sha3_256_shake (struct sha3_256_ctx *ctx,
-		size_t length,
-		uint8_t *dst)
+sha3_shake256_init (struct sha3_shake256_ctx *ctx)
 {
-  _sha3_pad_shake (&ctx->state, SHA3_256_BLOCK_SIZE, ctx->block, ctx->index);
-  while (length > SHA3_256_BLOCK_SIZE)
-    {
-      _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);
+  memset (ctx, 0, offsetof (struct sha3_shake256_ctx, block));
+}
 
-  sha3_256_init (ctx);
+void
+sha3_shake256_update (struct sha3_shake256_ctx *ctx,
+		      size_t length,
+		      const uint8_t *data)
+{
+  ctx->index = _nettle_sha3_update (&ctx->state,
+				    SHA3_256_BLOCK_SIZE, ctx->block,
+				    ctx->index, length, data);
 }
 
 void
-sha3_256_shake_output (struct sha3_256_ctx *ctx,
-		       size_t length,
-		       uint8_t *digest)
+sha3_shake256_output (struct sha3_shake256_ctx *ctx,
+		      size_t length,
+		      uint8_t *digest)
 {
   unsigned index, left;
 
@@ -126,3 +124,13 @@ sha3_256_shake_output (struct sha3_256_ctx *ctx,
     }
   ctx->index = ~length;
 }
+
+void
+sha3_256_shake (struct sha3_256_ctx *ctx,
+		size_t length,
+		uint8_t *dst)
+{
+  struct sha3_shake256_ctx *shake = (struct sha3_shake256_ctx *) ctx;
+  sha3_shake256_output (shake, length, dst);
+  sha3_shake256_init (shake);
+}
diff --git a/testsuite/shake256-test.c b/testsuite/shake256-test.c
index 016060e8..38326466 100644
--- a/testsuite/shake256-test.c
+++ b/testsuite/shake256-test.c
@@ -39,7 +39,7 @@
 const struct nettle_hash nettle_shake256 =
   {
    "shake256",
-   sizeof(struct sha3_256_ctx),
+   sizeof(struct sha3_shake256_ctx),
    0,
    SHA3_256_BLOCK_SIZE,
    (nettle_hash_init_func *) sha3_256_init,
@@ -52,18 +52,18 @@ test_incremental (const struct tstring *msg,
 		  const struct tstring *digest,
 		  size_t interval)
 {
-  struct sha3_256_ctx ctx;
+  struct sha3_shake256_ctx ctx;
   size_t offset = 0;
   uint8_t *buffer = xalloc (digest->length);
 
-  sha3_256_init (&ctx);
-  sha3_256_update (&ctx, msg->length, msg->data);
+  sha3_shake256_init (&ctx);
+  sha3_shake256_update (&ctx, msg->length, msg->data);
 
   while (offset < digest->length)
     {
       size_t to_read = MIN(digest->length - offset, interval);
 
-      sha3_256_shake_output (&ctx, to_read, buffer + offset);
+      sha3_shake256_output (&ctx, to_read, buffer + offset);
 
       offset += to_read;
     }
-- 
2.44.0

