+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
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);
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,
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)
}
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);
}
#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
/* 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
#include "sha3-internal.h"
const struct nettle_hash nettle_sha3_224
-= _NETTLE_HASH(sha3_224, SHA3_224);
+= _NETTLE_SHA3_HASH(sha3_224, SHA3_224);
# 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);
}
#include "sha3-internal.h"
const struct nettle_hash nettle_sha3_256
-= _NETTLE_HASH(sha3_256, SHA3_256);
+= _NETTLE_SHA3_HASH(sha3_256, SHA3_256);
# 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);
}
#include "sha3-internal.h"
const struct nettle_hash nettle_sha3_384
-= _NETTLE_HASH(sha3_384, SHA3_384);
+= _NETTLE_SHA3_HASH(sha3_384, SHA3_384);
# 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);
}
#include "sha3-internal.h"
const struct nettle_hash nettle_sha3_512
-= _NETTLE_HASH(sha3_512, SHA3_512);
+= _NETTLE_SHA3_HASH(sha3_512, SHA3_512);
# 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);
}
#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
#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 */
+ }
}
# 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);
}
/* 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
#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
}
# 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);
}
#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);
}
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);
}
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);
}
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,
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,