]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
New smaller struct sha3_ctx.
authorNiels Möller <nisse@lysator.liu.se>
Tue, 13 May 2025 18:13:01 +0000 (20:13 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Tue, 13 May 2025 18:13:01 +0000 (20:13 +0200)
24 files changed:
ChangeLog
ed448-shake256-pubkey.c
ed448-shake256-sign.c
ed448-shake256-verify.c
ed448-shake256.c
nettle-internal.h
sha3-224-meta.c
sha3-224.c
sha3-256-meta.c
sha3-256.c
sha3-384-meta.c
sha3-384.c
sha3-512-meta.c
sha3-512.c
sha3-internal.h
sha3-shake.c
sha3.c
sha3.h
shake128.c
shake256.c
testsuite/eddsa-sign-test.c
testsuite/eddsa-verify-test.c
testsuite/shake128-test.c
testsuite/shake256-test.c

index fcfd57cae5c67c0b9edb9cdaaec81d315aa1a7af..18cb7e6b36d70eba98565f1c823d1a77d3772747 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2025-05-13  Niels Möller  <nisse@lysator.liu.se>
+
+       Reduce size of sha3 context size to 216 bytes.
+       * sha3.h (struct sha3_ctx): New struct, replacing all sha3_*_ctx.
+       (struct sha3_128_ctx, struct sha3_224_ctx, struct sha3_256_ctx, struct sha3_384_ctx)
+       (struct sha3_512_ctx): Deleted.
+
+       * sha3-internal.h (_NETTLE_SHA3_HASH): New macro.
+
+       * sha3.c (sha3_xor_block, sha3_absorb): Deleted functions.
+       (sha3_init): New function, replacing all sha3_*_init.
+       (_nettle_sha3_update): Updated to take a struct sha3_ctx *
+       argument, updated all callers.
+       (_nettle_sha3_update) [WORDS_BIGENDIAN]: Use only a single 64-bit
+       word, 8 bytes, for input buffer.
+       (_nettle_sha3_update) [!WORDS_BIGENDIAN]: No buffering, xor input
+       into state directly.
+       (_nettle_sha3_pad): Updated to take a struct sha3_ctx * argument,
+       updated all callers.
+       (_nettle_sha3_digest): New function.
+
+       * sha3-shake.c (_nettle_sha3_shake_output): Updated to take a
+       struct sha3_ctx * argument, updated all callers.
+       (_nettle_sha3_shake_output) [WORDS_BIGENDIAN]: Use only a single
+       64-bit word, 8 bytes, for buffering partial output.
+       (_nettle_sha3_shake_output) [!WORDS_BIGENDIAN]: No buffering, copy
+       output directly from state.
+
+       * shake128.c (sha3_128_init): Deleted.
+       * sha3-224.c (sha3_224_init): Deleted.
+       * sha3-256.c (sha3_256_init): Deleted.
+       * sha3-384.c (sha3_384_init): Deleted.
+       * sha3-512.c (sha3_512_init): Deleted.
+
+       * nettle-internal.h (NETTLE_MAX_HASH_CONTEXT_SIZE): Lower,
+       streebog512_ctx is now the largest hash context struct.
+
 2025-04-28  Niels Möller  <nisse@lysator.liu.se>
 
        * bignum-random-prime.c (miller_rabin_pocklington): Adopt
index bde1827874498b9610472e93edcb5e9b26e840d7..ce031aacdcbeddbd8ad08c9364719a0dae954431 100644 (file)
@@ -44,14 +44,14 @@ void
 ed448_shake256_public_key (uint8_t *pub, const uint8_t *priv)
 {
   const struct ecc_curve *ecc = &_nettle_curve448;
-  struct sha3_256_ctx ctx;
+  struct sha3_ctx ctx;
   uint8_t digest[ED448_SIGNATURE_SIZE];
   mp_size_t itch = ecc->q.size + _eddsa_public_key_itch (ecc);
   mp_limb_t *scratch = gmp_alloc_limbs (itch);
 
 #define k scratch
 #define scratch_out (scratch + ecc->q.size)
-  sha3_256_init (&ctx);
+  sha3_init (&ctx);
   _eddsa_expand_key (ecc, &_nettle_ed448_shake256, &ctx, priv, digest, k);
   _eddsa_public_key (ecc, k, pub, scratch_out);
 
index c524593dd1dc3b3bd7d626bbad7b50c095c13deb..5d3cdbd5a0db034047fa477704ed274598fa5fa1 100644 (file)
@@ -52,10 +52,10 @@ ed448_shake256_sign (const uint8_t *pub,
   mp_limb_t *scratch = gmp_alloc_limbs (itch);
 #define k2 scratch
 #define scratch_out (scratch + ecc->q.size)
-  struct sha3_256_ctx ctx;
+  struct sha3_ctx ctx;
   uint8_t digest[ED448_SIGNATURE_SIZE];
 
-  sha3_256_init (&ctx);
+  sha3_init (&ctx);
   _eddsa_expand_key (ecc, eddsa, &ctx, priv, digest, k2);
 
   _eddsa_sign (ecc, eddsa, &ctx,
index af16f1079863592f94107b89ef8c929e555fe617..0134faae2593166fe7eb5673aa2835ca48c4a710 100644 (file)
@@ -50,11 +50,11 @@ ed448_shake256_verify (const uint8_t *pub,
   const struct ecc_curve *ecc = &_nettle_curve448;
   mp_size_t itch = 3*ecc->p.size + _eddsa_verify_itch (ecc);
   mp_limb_t *scratch = gmp_alloc_limbs (itch);
-  struct sha3_256_ctx ctx;
+  struct sha3_ctx ctx;
   int res;
 #define A scratch
 #define scratch_out (scratch + 3*ecc->p.size)
-  sha3_256_init (&ctx);
+  sha3_init (&ctx);
 
   res = (_eddsa_decompress (ecc,
                            A, pub, scratch_out)
index 4522a158c5c6ec91aefa475ae94a0b80a371dc5d..b00150d4d839e7025e62b794ca23429e7605d38d 100644 (file)
@@ -52,7 +52,7 @@ ed448_dom(void *ctx)
 }
 
 static void
-ed448_digest(struct sha3_256_ctx *ctx, uint8_t *digest)
+ed448_digest(struct sha3_ctx *ctx, uint8_t *digest)
 {
   sha3_256_shake(ctx, 2*ED448_KEY_SIZE, digest);
 }
index 81d06e80e68bb131b1e63794b619cc5d141820bd..1aed1007f2a7dff1ab05bbb36525a4aff87ddc06 100644 (file)
@@ -39,7 +39,7 @@
 #include <stdlib.h>
 
 /* For definition of NETTLE_MAX_HASH_CONTEXT_SIZE. */
-#include "sha3.h"
+#include "streebog.h"
 
 /* Temporary allocation, for systems that don't support alloca. Note
  * that the allocation requests should always be reasonably small, so
@@ -74,7 +74,7 @@
 /* Limits that apply to systems that don't have alloca */
 #define NETTLE_MAX_HASH_BLOCK_SIZE 144  /* For sha3_224*/
 #define NETTLE_MAX_HASH_DIGEST_SIZE 64
-#define NETTLE_MAX_HASH_CONTEXT_SIZE (sizeof(struct sha3_224_ctx))
+#define NETTLE_MAX_HASH_CONTEXT_SIZE (sizeof(struct streebog512_ctx))
 #define NETTLE_MAX_SEXP_ASSOC 17
 #define NETTLE_MAX_CIPHER_BLOCK_SIZE 32
 #define NETTLE_MAX_CIPHER_KEY_SIZE 32
index bf39bc3b128168116a6909b56a1a1239084af22d..6c5a76cdf70b1b15795aa5e11b47a5138dfd6568 100644 (file)
@@ -39,4 +39,4 @@
 #include "sha3-internal.h"
 
 const struct nettle_hash nettle_sha3_224
-= _NETTLE_HASH(sha3_224, SHA3_224);
+= _NETTLE_SHA3_HASH(sha3_224, SHA3_224);
index 08afce69fee7229343f6d7f4f0d49c5c9dc1a263..0b20d19b85b9032646cf70df2231fe7d287827db 100644 (file)
 # include "config.h"
 #endif
 
-#include <stddef.h>
-#include <string.h>
-
 #include "sha3.h"
 #include "sha3-internal.h"
 
-#include "nettle-write.h"
-
-void
-sha3_224_init (struct sha3_224_ctx *ctx)
-{
-  memset (ctx, 0, offsetof (struct sha3_224_ctx, block));
-}
-
 void
-sha3_224_update (struct sha3_224_ctx *ctx, size_t length, const uint8_t *data)
+sha3_224_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data)
 {
-  ctx->index = _nettle_sha3_update (&ctx->state,
-                                   SHA3_224_BLOCK_SIZE, ctx->block,
-                                   ctx->index, length, data);
+  _nettle_sha3_update (ctx, SHA3_224_BLOCK_SIZE >> 3, length, data);
 }
 
 void
-sha3_224_digest(struct sha3_224_ctx *ctx, uint8_t *digest)
+sha3_224_digest(struct sha3_ctx *ctx, uint8_t *digest)
 {
-  _sha3_pad_hash (&ctx->state, SHA3_224_BLOCK_SIZE, ctx->block, ctx->index);
-  _nettle_write_le64 (SHA3_224_DIGEST_SIZE, digest, ctx->state.a);
-  sha3_224_init (ctx);
+  _nettle_sha3_digest (ctx, SHA3_224_BLOCK_SIZE >> 3, SHA3_224_DIGEST_SIZE, digest);
 }
index 649d74228d4d231dc14b131dc132497b58acc4ff..40e841e7d850900a2e595b19d0eea8abc729d696 100644 (file)
@@ -39,4 +39,4 @@
 #include "sha3-internal.h"
 
 const struct nettle_hash nettle_sha3_256
-= _NETTLE_HASH(sha3_256, SHA3_256);
+= _NETTLE_SHA3_HASH(sha3_256, SHA3_256);
index c347e13bc3689d97e449223f37f66ea68d43c97e..557c69f31af03fb739551bede9c1bb4d1515d602 100644 (file)
 # include "config.h"
 #endif
 
-#include <stddef.h>
-#include <string.h>
-
 #include "sha3.h"
 #include "sha3-internal.h"
 
-#include "nettle-write.h"
-
-void
-sha3_256_init (struct sha3_256_ctx *ctx)
-{
-  memset (ctx, 0, offsetof (struct sha3_256_ctx, block));
-}
-
 void
-sha3_256_update (struct sha3_256_ctx *ctx, size_t length, const uint8_t *data)
+sha3_256_update (struct sha3_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);
+  _nettle_sha3_update (ctx, SHA3_256_BLOCK_SIZE >> 3, length, data);
 }
 
 void
-sha3_256_digest(struct sha3_256_ctx *ctx, uint8_t *digest)
+sha3_256_digest(struct sha3_ctx *ctx, uint8_t *digest)
 {
-  _sha3_pad_hash (&ctx->state, SHA3_256_BLOCK_SIZE, ctx->block, ctx->index);
-  _nettle_write_le64 (SHA3_256_DIGEST_SIZE, digest, ctx->state.a);
-  sha3_256_init (ctx);
+  _nettle_sha3_digest (ctx, SHA3_256_BLOCK_SIZE >> 3, SHA3_256_DIGEST_SIZE, digest);
 }
index 38373394043ea027fcd12ee3d637f414401949ac..2c03d711d0f141d4d958b052cd2f0f0ba1b0419a 100644 (file)
@@ -39,4 +39,4 @@
 #include "sha3-internal.h"
 
 const struct nettle_hash nettle_sha3_384
-= _NETTLE_HASH(sha3_384, SHA3_384);
+= _NETTLE_SHA3_HASH(sha3_384, SHA3_384);
index ea8dd038ee0633ee2fcd65877285e52ac2514a85..13a4ef29c0444ed1b8ef6e6f2ababa92c9c618e0 100644 (file)
 # include "config.h"
 #endif
 
-#include <stddef.h>
-#include <string.h>
-
 #include "sha3.h"
 #include "sha3-internal.h"
 
-#include "nettle-write.h"
-
-void
-sha3_384_init (struct sha3_384_ctx *ctx)
-{
-  memset (ctx, 0, offsetof (struct sha3_384_ctx, block));
-}
-
 void
-sha3_384_update (struct sha3_384_ctx *ctx, size_t length, const uint8_t *data)
+sha3_384_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data)
 {
-  ctx->index = _nettle_sha3_update (&ctx->state,
-                                   SHA3_384_BLOCK_SIZE, ctx->block,
-                                   ctx->index, length, data);
+  _nettle_sha3_update (ctx, SHA3_384_BLOCK_SIZE >> 3, length, data);
 }
 
 void
-sha3_384_digest(struct sha3_384_ctx *ctx, uint8_t *digest)
+sha3_384_digest(struct sha3_ctx *ctx, uint8_t *digest)
 {
-  _sha3_pad_hash (&ctx->state, SHA3_384_BLOCK_SIZE, ctx->block, ctx->index);
-  _nettle_write_le64 (SHA3_384_DIGEST_SIZE, digest, ctx->state.a);
-  sha3_384_init (ctx);
+  _nettle_sha3_digest (ctx, SHA3_384_BLOCK_SIZE >> 3, SHA3_384_DIGEST_SIZE, digest);
 }
index aff96373d0df5bd7f886f22578237afc6ef67af0..61c22220b31a49d7520cadd1c10f1253dd78e35d 100644 (file)
@@ -39,4 +39,4 @@
 #include "sha3-internal.h"
 
 const struct nettle_hash nettle_sha3_512
-= _NETTLE_HASH(sha3_512, SHA3_512);
+= _NETTLE_SHA3_HASH(sha3_512, SHA3_512);
index 9ae014dca1489fdbe00982b6a1370585baf9bc77..632c50c0dac190481a22655cecd2a35a02901eb1 100644 (file)
 # include "config.h"
 #endif
 
-#include <stddef.h>
-#include <string.h>
-
 #include "sha3.h"
 #include "sha3-internal.h"
 
-#include "nettle-write.h"
-
-void
-sha3_512_init (struct sha3_512_ctx *ctx)
-{
-  memset (ctx, 0, offsetof (struct sha3_512_ctx, block));
-}
-
 void
-sha3_512_update (struct sha3_512_ctx *ctx, size_t length, const uint8_t *data)
+sha3_512_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data)
 {
-  ctx->index = _nettle_sha3_update (&ctx->state,
-                                   SHA3_512_BLOCK_SIZE, ctx->block,
-                                   ctx->index, length, data);
+  _nettle_sha3_update (ctx, SHA3_512_BLOCK_SIZE >> 3, length, data);
 }
 
 void
-sha3_512_digest(struct sha3_512_ctx *ctx, uint8_t *digest)
+sha3_512_digest(struct sha3_ctx *ctx, uint8_t *digest)
 {
-  _sha3_pad_hash (&ctx->state, SHA3_512_BLOCK_SIZE, ctx->block, ctx->index);
-  _nettle_write_le64 (SHA3_512_DIGEST_SIZE, digest, ctx->state.a);
-  sha3_512_init (ctx);
+  _nettle_sha3_digest (ctx, SHA3_512_BLOCK_SIZE >> 3, SHA3_512_DIGEST_SIZE, digest);
 }
index 669b9449d8350eed215a71f91f2d8e008b1193fb..8a09db458aafed25d7f2227136b5da17fc5ca20c 100644 (file)
 #define SHA3_HASH_MAGIC 6
 #define SHA3_SHAKE_MAGIC 0x1f
 
-unsigned
-_nettle_sha3_update (struct sha3_state *state,
-                    unsigned block_size, uint8_t *block,
-                    unsigned pos,
-                    size_t length, const uint8_t *data);
-
+void
+_nettle_sha3_init (struct sha3_ctx *ctx);
 
+/* For all functions, the block_size is in units of uint64_t words. */
 void
-_nettle_sha3_pad (struct sha3_state *state,
-                 unsigned block_size, uint8_t *block, unsigned pos, uint8_t magic);
+_nettle_sha3_update (struct sha3_ctx *ctx, unsigned block_size,
+                    size_t length, const uint8_t *data);
 
-#define _sha3_pad_hash(state, block_size, block, pos) do {             \
-    _nettle_sha3_pad (state, block_size, block, pos, SHA3_HASH_MAGIC); \
-    sha3_permute (state);                                              \
-  } while (0)
+void
+_nettle_sha3_pad (struct sha3_ctx *ctx, unsigned block_size, uint8_t magic);
 
-#define _sha3_pad_shake(state, block_size, block, pos) \
-  _nettle_sha3_pad (state, block_size, block, pos, SHA3_SHAKE_MAGIC)
+void
+_nettle_sha3_digest (struct sha3_ctx *ctx, unsigned block_size,
+                    unsigned digest_size, uint8_t *digest);
 
 void
-_nettle_sha3_shake (struct sha3_state *state,
-                   unsigned block_size, uint8_t *block,
-                   unsigned index,
+_nettle_sha3_shake (struct sha3_ctx *ctx, unsigned block_size,
                    size_t length, uint8_t *dst);
 
-unsigned
-_nettle_sha3_shake_output (struct sha3_state *state,
-                          unsigned block_size, uint8_t *block,
-                          unsigned index,
+void
+_nettle_sha3_shake_output (struct sha3_ctx *ctx, unsigned block_size,
                           size_t length, uint8_t *dst);
 
+#define _NETTLE_SHA3_HASH(name, NAME) {                \
+ #name,                                                \
+ sizeof(struct sha3_ctx),                      \
+ NAME##_DIGEST_SIZE,                           \
+ NAME##_BLOCK_SIZE,                            \
+ (nettle_hash_init_func *) sha3_init,          \
+ (nettle_hash_update_func *) name##_update,    \
+ (nettle_hash_digest_func *) name##_digest     \
+}
+
 #endif
index d9312bbb7da54c48f9f4f7df7ace14e21b840d6a..3e0ab634b44cf871b9c4407518b10f48a3f1683b 100644 (file)
 #include "sha3.h"
 #include "sha3-internal.h"
 
+#include "bswap-internal.h"
+#include "macros.h"
 #include "nettle-write.h"
 
 void
-_nettle_sha3_shake (struct sha3_state *state,
-                   unsigned block_size, uint8_t *block,
-                   unsigned index,
+_nettle_sha3_shake (struct sha3_ctx *ctx, unsigned block_size,
                    size_t length, uint8_t *dst)
 {
-  _sha3_pad_shake (state, block_size, block, index);
+  _nettle_sha3_pad (ctx, block_size, SHA3_SHAKE_MAGIC);
+
+  /* Use byte units. */
+  block_size <<= 3;
 
   while (length > block_size)
     {
-      sha3_permute (state);
-      _nettle_write_le64 (block_size, dst, state->a);
-      length -= block_size;
-      dst += block_size;
+      sha3_permute (&ctx->state);
+      _nettle_write_le64 (block_size, dst, ctx->state.a);
+      length -= block_size; dst += block_size;
     }
 
-  sha3_permute (state);
-  _nettle_write_le64 (length, dst, state->a);
+  sha3_permute (&ctx->state);
+  _nettle_write_le64 (length, dst, ctx->state.a);
+  sha3_init (ctx);
 }
 
-unsigned
-_nettle_sha3_shake_output (struct sha3_state *state,
-                          unsigned block_size, uint8_t *block,
-                          unsigned index,
+void
+_nettle_sha3_shake_output (struct sha3_ctx *ctx, unsigned block_size,
                           size_t length, uint8_t *dst)
 {
-  unsigned left;
+  unsigned index = ctx->index;
+  unsigned block_bytes = block_size << 3;
 
-  /* We use one's complement of the index value to indicate SHAKE is
-     initialized. */
-  if (index < block_size)
+  if (!ctx->shake_flag)
     {
       /* This is the first call of _shake_output.  */
-      _sha3_pad_shake (state, block_size, block, index);
+      _nettle_sha3_pad (ctx, block_size, SHA3_SHAKE_MAGIC);
       /* Point at the end of block to trigger fill in of the buffer.  */
-      index = block_size;
-    }
-  else
-    index = ~index;
-
-  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);
-    }
-  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;
+      index = block_bytes;
+      ctx->shake_flag = 1;
     }
 
-  sha3_permute (state);
-  /* Fill in the buffer for next call.  */
-  _nettle_write_le64 (block_size, block, state->a);
-  memcpy (dst, block, length);
-  return ~length;
+  assert (index <= block_bytes);
+  {
+#if WORDS_BIGENDIAN
+    unsigned byte_index = index & 7;
+
+    if (byte_index)
+      {
+       unsigned left = 8 - byte_index;
+       if (length <= left)
+         {
+           memcpy (dst, ctx->block.b + byte_index, length);
+           ctx->index = index + length;
+           return;
+         }
+       memcpy (dst, ctx->block.b + byte_index, left);
+       dst += left; length -= left; index += left;
+      }
+
+    /* Switch to units of words */
+    index >>= 3;
+
+    for (; length > 0; length -= 8, dst += 8, index++)
+      {
+       if (index == block_size)
+         {
+           sha3_permute (&ctx->state);
+           index = 0;
+         }
+       if (length < 8)
+         {
+           ctx->block.u64 = nettle_bswap64 (ctx->state.a[index]);
+           memcpy (dst, ctx->block.b, length);
+           break;
+         }
+       LE_WRITE_UINT64(dst, ctx->state.a[index]);
+      }
+    ctx->index = (index << 3) + length;
+#else /* !WORDS_BIGENDIAN */
+    size_t left = block_bytes - index;
+    if (length <= left)
+      {
+       memcpy (dst, ((const uint8_t *) ctx->state.a) + index, length);
+       ctx->index = index + length;
+       return;
+      }
+    else
+      {
+       memcpy (dst, ((const uint8_t *) ctx->state.a) + index, left);
+       length -= left;
+       dst += left;
+      }
+
+    /* Write full blocks.  */
+    for (; length > block_bytes; length -= block_bytes, dst += block_bytes)
+      {
+       sha3_permute (&ctx->state);
+       _nettle_write_le64 (block_bytes, dst, ctx->state.a);
+      }
+
+    sha3_permute (&ctx->state);
+    memcpy (dst, ctx->state.a, length);
+    ctx->index = length;
+#endif /* !WORDS_BIGENDIAN */
+  }
 }
diff --git a/sha3.c b/sha3.c
index d2f27323fc7cecca5ef312e949636e6f262bf08d..f378b9c683abb543dc6f2ee17a67fc90f851039e 100644 (file)
--- a/sha3.c
+++ b/sha3.c
 # include "config.h"
 #endif
 
-#include <assert.h>
 #include <string.h>
 
 #include "sha3.h"
 #include "sha3-internal.h"
 
+#include "bswap-internal.h"
 #include "macros.h"
-#include "md-internal.h"
 #include "memxor.h"
+#include "nettle-write.h"
 
-#if WORDS_BIGENDIAN
-static void
-sha3_xor_block (struct sha3_state *state, unsigned length, const uint8_t *data)
-{
-  assert ( (length & 7) == 0);
-  {    
-    uint64_t *p;
-    for (p = state->a; length > 0; p++, length -= 8, data += 8)
-      *p ^= LE_READ_UINT64 (data);
-  }
-}
-#else /* !WORDS_BIGENDIAN */
-#define sha3_xor_block(state, length, data) memxor (state->a, data, length)
-#endif
-
-static void
-sha3_absorb (struct sha3_state *state, unsigned length, const uint8_t *data)
+void
+sha3_init (struct sha3_ctx *ctx)
 {
-  sha3_xor_block (state, length, data);
-  sha3_permute (state);
+  memset (ctx, 0, offsetof (struct sha3_ctx, block));
 }
 
-unsigned
-_nettle_sha3_update (struct sha3_state *state,
-                    unsigned block_size, uint8_t *block,
-                    unsigned pos,
+void
+_nettle_sha3_update (struct sha3_ctx *ctx, unsigned block_size,
                     size_t length, const uint8_t *data)
 {
-  assert (pos < block_size);
+#if WORDS_BIGENDIAN
+  unsigned byte_index = ctx->index & 7;
+  unsigned index = ctx->index >> 3;
 
-  if (!length)
-    return pos;
+  if (byte_index > 0)
+    {
+      unsigned left = sizeof (ctx->block) - byte_index;
+      if (length < left)
+       {
+         memcpy (ctx->block.b + byte_index, data, length);
+         ctx->index += length;
+         return;
+       }
+      memcpy (ctx->block.b + byte_index, data, left);
+      data += left; length -= left;
+
+      ctx->state.a[index++] ^= nettle_bswap64 (ctx->block.u64);
+      if (index == block_size)
+       {
+         sha3_permute (&ctx->state);
+         index = 0;
+       }
+    }
 
-  if (pos > 0)
+  for (; length >= 8; length -= 8, data += 8)
     {
-      MD_FILL_OR_RETURN_INDEX (block_size, block, pos, length, data);
-      sha3_absorb (state, block_size, block);
+      ctx->state.a[index++] ^= LE_READ_UINT64 (data);
+      if (index == block_size)
+       {
+         sha3_permute (&ctx->state);
+         index = 0;
+       }
+    }
+  memcpy (ctx->block.b, data, length);
+  ctx->index = (index << 3) + length;
+#else /* !WORDS_BIGENDIAN */
+  /* Switch to units of bytes. */
+  block_size <<= 3;
+  if (ctx->index > 0)
+    {
+      unsigned left = block_size - ctx->index;
+      if (length < left)
+       {
+         memxor ((uint8_t *) ctx->state.a + ctx->index, data, length);
+         ctx->index += length;
+         return;
+       }
+      memxor ((uint8_t *) ctx->state.a + ctx->index, data, left);
+      data += left; length -= left;
+      ctx->index = 0;
+      sha3_permute (&ctx->state);
     }
   for (; length >= block_size; length -= block_size, data += block_size)
-    sha3_absorb (state, block_size, data);
-
-  memcpy (block, data, length);
-  return length;
+    {
+      memxor ((uint8_t *) ctx->state.a, data, block_size);
+      sha3_permute (&ctx->state);
+    }
+  memxor ((uint8_t *) ctx->state.a, data, length);
+  ctx->index = length;
+#endif /* !WORDS_BIGENDIAN */
 }
 
 void
-_nettle_sha3_pad (struct sha3_state *state,
-                 unsigned block_size, uint8_t *block, unsigned pos, uint8_t magic)
+_nettle_sha3_pad (struct sha3_ctx *ctx, unsigned block_size, uint8_t magic)
 {
-  assert (pos < block_size);
-  block[pos++] = magic;
+#if WORDS_BIGENDIAN
+  unsigned byte_index = ctx->index & 7;
+  unsigned word_index = ctx->index >> 3;
 
-  memset (block + pos, 0, block_size - pos);
-  block[block_size - 1] |= 0x80;
+  ctx->block.b[byte_index++] = magic;
+  memset (ctx->block.b + byte_index, 0, 8 - byte_index);
+  ctx->state.a[word_index] ^= nettle_bswap64 (ctx->block.u64);
+#else /* !WORDS_BIGENDIAN */
+  ((uint8_t *) ctx->state.a)[ctx->index] ^= magic;
+#endif /* !WORDS_BIGENDIAN */
+  ctx->state.a[block_size - 1] ^= (uint64_t) 1 << 63;
+}
 
-  sha3_xor_block (state, block_size, block);
+void
+_nettle_sha3_digest (struct sha3_ctx *ctx, unsigned block_size,
+                    unsigned digest_size, uint8_t *digest)
+{
+  _nettle_sha3_pad (ctx, block_size, SHA3_HASH_MAGIC);
+  sha3_permute (&ctx->state);
+  _nettle_write_le64 (digest_size, digest, ctx->state.a);
+  sha3_init (ctx);
 }
diff --git a/sha3.h b/sha3.h
index c499f395b6ce4bc28abf953dfac981c265598b00..7e4a7963922b2c60e5237ec4843c0b3ecefb15b9 100644 (file)
--- a/sha3.h
+++ b/sha3.h
@@ -42,22 +42,18 @@ extern "C" {
 
 /* Name mangling */
 #define sha3_permute nettle_sha3_permute
-#define sha3_128_init nettle_sha3_128_init
+#define sha3_init nettle_sha3_init
 #define sha3_128_update nettle_sha3_128_update
 #define sha3_128_shake nettle_sha3_128_shake
 #define sha3_128_shake_output nettle_sha3_128_shake_output
-#define sha3_224_init nettle_sha3_224_init
 #define sha3_224_update nettle_sha3_224_update
 #define sha3_224_digest nettle_sha3_224_digest
-#define sha3_256_init nettle_sha3_256_init
 #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_384_init nettle_sha3_384_init
 #define sha3_384_update nettle_sha3_384_update
 #define sha3_384_digest nettle_sha3_384_digest
-#define sha3_512_init nettle_sha3_512_init
 #define sha3_512_update nettle_sha3_512_update
 #define sha3_512_digest nettle_sha3_512_digest
 
@@ -98,98 +94,64 @@ sha3_permute (struct sha3_state *state);
 #define SHA3_512_DIGEST_SIZE 64
 #define SHA3_512_BLOCK_SIZE 72
 
-struct sha3_128_ctx
+struct sha3_ctx
 {
   struct sha3_state state;
+  /* The position in current block of next input byte (for update) or
+     next output byte (for shake). */
   unsigned index;
-  uint8_t block[SHA3_128_BLOCK_SIZE];
+  /* Set when shake output has been initialized. */
+  int shake_flag;
+  /* Buffer for partial words; input and output from the state is
+     handled one uint64_t at a time. */
+  union nettle_block8 block;
 };
 
 void
-sha3_128_init (struct sha3_128_ctx *ctx);
+sha3_init (struct sha3_ctx *ctx);
 
 void
-sha3_128_update (struct sha3_128_ctx *ctx, size_t length, const uint8_t *data);
+sha3_128_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data);
 
 void
-sha3_128_shake (struct sha3_128_ctx *ctx, size_t length, uint8_t *digest);
+sha3_128_shake (struct sha3_ctx *ctx, size_t length, uint8_t *digest);
 
 void
-sha3_128_shake_output (struct sha3_128_ctx *ctx, size_t length, uint8_t *digest);
-
-struct sha3_224_ctx
-{
-  struct sha3_state state;
-  unsigned index;
-  uint8_t block[SHA3_224_BLOCK_SIZE];
-};
-
-void
-sha3_224_init (struct sha3_224_ctx *ctx);
+sha3_128_shake_output (struct sha3_ctx *ctx, size_t length, uint8_t *digest);
 
 void
-sha3_224_update (struct sha3_224_ctx *ctx, size_t length, const uint8_t *data);
-
-void
-sha3_224_digest(struct sha3_224_ctx *ctx, uint8_t *digest);
-
-struct sha3_256_ctx
-{
-  struct sha3_state state;
-  unsigned index;
-  uint8_t block[SHA3_256_BLOCK_SIZE];
-};
+sha3_224_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data);
 
 void
-sha3_256_init (struct sha3_256_ctx *ctx);
+sha3_224_digest(struct sha3_ctx *ctx, uint8_t *digest);
 
 void
-sha3_256_update (struct sha3_256_ctx *ctx, size_t length, const uint8_t *data);
+sha3_256_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data);
 
 void
-sha3_256_digest(struct sha3_256_ctx *ctx, uint8_t *digest);
+sha3_256_digest(struct sha3_ctx *ctx, uint8_t *digest);
 
 /* Alternative digest function implementing shake256, with arbitrary
    digest size */
 void
-sha3_256_shake(struct sha3_256_ctx *ctx, size_t length, uint8_t *digest);
+sha3_256_shake(struct sha3_ctx *ctx, size_t length, uint8_t *digest);
 
 /* 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, size_t length, uint8_t *digest);
-
-struct sha3_384_ctx
-{
-  struct sha3_state state;
-  unsigned index;
-  uint8_t block[SHA3_384_BLOCK_SIZE];
-};
-
-void
-sha3_384_init (struct sha3_384_ctx *ctx);
+sha3_256_shake_output(struct sha3_ctx *ctx, size_t length, uint8_t *digest);
 
 void
-sha3_384_update (struct sha3_384_ctx *ctx, size_t length, const uint8_t *data);
-
-void
-sha3_384_digest(struct sha3_384_ctx *ctx, uint8_t *digest);
-
-struct sha3_512_ctx
-{
-  struct sha3_state state;
-  unsigned index;
-  uint8_t block[SHA3_512_BLOCK_SIZE];
-};
+sha3_384_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data);
 
 void
-sha3_512_init (struct sha3_512_ctx *ctx);
+sha3_384_digest(struct sha3_ctx *ctx, uint8_t *digest);
 
 void
-sha3_512_update (struct sha3_512_ctx *ctx, size_t length, const uint8_t *data);
+sha3_512_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data);
 
 void
-sha3_512_digest(struct sha3_512_ctx *ctx, uint8_t *digest);
+sha3_512_digest(struct sha3_ctx *ctx, uint8_t *digest);
 
 #ifdef __cplusplus
 }
index f0c68e7d88dcbe31d57316074fc011d58aecb4ac..5f8b9610010e267f6ddac6d43cbe409be72e9179 100644 (file)
 # include "config.h"
 #endif
 
-#include <string.h>
-
 #include "sha3.h"
 #include "sha3-internal.h"
 
 void
-sha3_128_init (struct sha3_128_ctx *ctx)
-{
-  memset (ctx, 0, offsetof (struct sha3_128_ctx, block));
-}
-
-void
-sha3_128_update (struct sha3_128_ctx *ctx, size_t length, const uint8_t *data)
+sha3_128_update (struct sha3_ctx *ctx, size_t length, const uint8_t *data)
 {
-  ctx->index = _nettle_sha3_update (&ctx->state,
-                                   SHA3_128_BLOCK_SIZE, ctx->block,
-                                   ctx->index, length, data);
+  _nettle_sha3_update (ctx, SHA3_128_BLOCK_SIZE >> 3, length, data);
 }
 
 void
-sha3_128_shake (struct sha3_128_ctx *ctx, size_t length, uint8_t *dst)
+sha3_128_shake (struct sha3_ctx *ctx, size_t length, uint8_t *dst)
 {
-  _nettle_sha3_shake (&ctx->state, sizeof (ctx->block), ctx->block, ctx->index, length, dst);
-  sha3_128_init (ctx);
+  _nettle_sha3_shake (ctx, SHA3_128_BLOCK_SIZE >> 3, length, dst);
 }
 
 void
-sha3_128_shake_output (struct sha3_128_ctx *ctx, size_t length, uint8_t *digest)
+sha3_128_shake_output (struct sha3_ctx *ctx, size_t length, uint8_t *digest)
 {
-  ctx->index =
-    _nettle_sha3_shake_output (&ctx->state,
-                              sizeof (ctx->block), ctx->block, ctx->index,
-                              length, digest);
+  _nettle_sha3_shake_output (ctx, SHA3_128_BLOCK_SIZE >> 3, length, digest);
 }
index de72cf96d2355bf8534ce2c9aaeacb94f6ef1382..05263b6ef5f035f91899baffdd68bbd62d2d8b48 100644 (file)
 #include "sha3-internal.h"
 
 void
-sha3_256_shake (struct sha3_256_ctx *ctx, size_t length, uint8_t *dst)
+sha3_256_shake (struct sha3_ctx *ctx, size_t length, uint8_t *dst)
 {
-  _nettle_sha3_shake (&ctx->state, sizeof (ctx->block), ctx->block, ctx->index, length, dst);
-  sha3_256_init (ctx);
+  _nettle_sha3_shake (ctx, SHA3_256_BLOCK_SIZE >> 3, length, dst);
 }
 
 void
-sha3_256_shake_output (struct sha3_256_ctx *ctx, size_t length, uint8_t *digest)
+sha3_256_shake_output (struct sha3_ctx *ctx, size_t length, uint8_t *digest)
 {
-  ctx->index =
-    _nettle_sha3_shake_output (&ctx->state,
-                              sizeof (ctx->block), ctx->block, ctx->index,
-                              length, digest);
+  _nettle_sha3_shake_output (ctx, SHA3_256_BLOCK_SIZE >> 3, length, digest);
 }
index 2ea1e4bd5b8920d89ee33eba88d04ee307cfe417..1bc80c94d4d443e411cb5f873fffbb229852d5b8 100644 (file)
@@ -119,9 +119,9 @@ test_ed448_sign (const struct tstring *public,
                 const struct tstring *msg,
                 const struct tstring *ref)
 {
-  struct sha3_256_ctx ctx;
+  struct sha3_ctx ctx;
 
-  sha3_256_init (&ctx);
+  sha3_init (&ctx);
   test_eddsa_sign (&_nettle_curve448, &_nettle_ed448_shake256, &ctx,
                   public, private, msg, ref);
 }
index cc853a55ea82237e429e2761026b22895afdf1a2..de85062662172fb55c2ff4de755fdcf1353dbe8d 100644 (file)
@@ -142,9 +142,9 @@ test_ed448 (const uint8_t *pub,
            const struct tstring *msg,
            const uint8_t *signature)
 {
-  struct sha3_256_ctx ctx;
+  struct sha3_ctx ctx;
 
-  sha3_256_init (&ctx);
+  sha3_init (&ctx);
   test_eddsa (&_nettle_curve448, &_nettle_ed448_shake256, &ctx,
              pub, msg, signature);
 }
index fd55b4b2fab2c68b16181726cfc80775188bffa2..d1b71de96ce5e7b186cb2efec4f7589539e7d1a7 100644 (file)
@@ -37,9 +37,9 @@
 const struct nettle_xof nettle_shake128 =
   {
    "shake128",
-   sizeof(struct sha3_128_ctx),
+   sizeof(struct sha3_ctx),
    SHA3_128_BLOCK_SIZE,
-   (nettle_hash_init_func *) sha3_128_init,
+   (nettle_hash_init_func *) sha3_init,
    (nettle_hash_update_func *) sha3_128_update,
    (nettle_output_func *) sha3_128_shake,
    (nettle_output_func *) sha3_128_shake_output,
index 93e1107e0cf43af5f77077e22099802b4bc018cf..9f5d9cedbaf069996542d717932f02068a16b331 100644 (file)
@@ -39,9 +39,9 @@
 const struct nettle_xof nettle_shake256 =
   {
    "shake256",
-   sizeof(struct sha3_256_ctx),
+   sizeof(struct sha3_ctx),
    SHA3_256_BLOCK_SIZE,
-   (nettle_hash_init_func *) sha3_256_init,
+   (nettle_hash_init_func *) sha3_init,
    (nettle_hash_update_func *) sha3_256_update,
    (nettle_output_func *) sha3_256_shake,
    (nettle_output_func *) sha3_256_shake_output,