From: Niels Möller Date: Tue, 13 May 2025 18:13:01 +0000 (+0200) Subject: New smaller struct sha3_ctx. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=07df157050197e71da37144709478287b9ac2d13;p=thirdparty%2Fnettle.git New smaller struct sha3_ctx. --- diff --git a/ChangeLog b/ChangeLog index fcfd57ca..18cb7e6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2025-05-13 Niels Möller + + 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 * bignum-random-prime.c (miller_rabin_pocklington): Adopt diff --git a/ed448-shake256-pubkey.c b/ed448-shake256-pubkey.c index bde18278..ce031aac 100644 --- a/ed448-shake256-pubkey.c +++ b/ed448-shake256-pubkey.c @@ -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); diff --git a/ed448-shake256-sign.c b/ed448-shake256-sign.c index c524593d..5d3cdbd5 100644 --- a/ed448-shake256-sign.c +++ b/ed448-shake256-sign.c @@ -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, diff --git a/ed448-shake256-verify.c b/ed448-shake256-verify.c index af16f107..0134faae 100644 --- a/ed448-shake256-verify.c +++ b/ed448-shake256-verify.c @@ -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) diff --git a/ed448-shake256.c b/ed448-shake256.c index 4522a158..b00150d4 100644 --- a/ed448-shake256.c +++ b/ed448-shake256.c @@ -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); } diff --git a/nettle-internal.h b/nettle-internal.h index 81d06e80..1aed1007 100644 --- a/nettle-internal.h +++ b/nettle-internal.h @@ -39,7 +39,7 @@ #include /* 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 diff --git a/sha3-224-meta.c b/sha3-224-meta.c index bf39bc3b..6c5a76cd 100644 --- a/sha3-224-meta.c +++ b/sha3-224-meta.c @@ -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); diff --git a/sha3-224.c b/sha3-224.c index 08afce69..0b20d19b 100644 --- a/sha3-224.c +++ b/sha3-224.c @@ -35,32 +35,17 @@ # include "config.h" #endif -#include -#include - #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); } diff --git a/sha3-256-meta.c b/sha3-256-meta.c index 649d7422..40e841e7 100644 --- a/sha3-256-meta.c +++ b/sha3-256-meta.c @@ -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); diff --git a/sha3-256.c b/sha3-256.c index c347e13b..557c69f3 100644 --- a/sha3-256.c +++ b/sha3-256.c @@ -35,32 +35,17 @@ # include "config.h" #endif -#include -#include - #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); } diff --git a/sha3-384-meta.c b/sha3-384-meta.c index 38373394..2c03d711 100644 --- a/sha3-384-meta.c +++ b/sha3-384-meta.c @@ -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); diff --git a/sha3-384.c b/sha3-384.c index ea8dd038..13a4ef29 100644 --- a/sha3-384.c +++ b/sha3-384.c @@ -35,32 +35,17 @@ # include "config.h" #endif -#include -#include - #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); } diff --git a/sha3-512-meta.c b/sha3-512-meta.c index aff96373..61c22220 100644 --- a/sha3-512-meta.c +++ b/sha3-512-meta.c @@ -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); diff --git a/sha3-512.c b/sha3-512.c index 9ae014dc..632c50c0 100644 --- a/sha3-512.c +++ b/sha3-512.c @@ -35,32 +35,17 @@ # include "config.h" #endif -#include -#include - #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); } diff --git a/sha3-internal.h b/sha3-internal.h index 669b9449..8a09db45 100644 --- a/sha3-internal.h +++ b/sha3-internal.h @@ -39,35 +39,37 @@ #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 diff --git a/sha3-shake.c b/sha3-shake.c index d9312bbb..3e0ab634 100644 --- a/sha3-shake.c +++ b/sha3-shake.c @@ -41,76 +41,109 @@ #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 d2f27323..f378b9c6 100644 --- a/sha3.c +++ b/sha3.c @@ -35,70 +35,110 @@ # include "config.h" #endif -#include #include #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 c499f395..7e4a7963 100644 --- 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 } diff --git a/shake128.c b/shake128.c index f0c68e7d..5f8b9610 100644 --- a/shake128.c +++ b/shake128.c @@ -36,37 +36,23 @@ # include "config.h" #endif -#include - #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); } diff --git a/shake256.c b/shake256.c index de72cf96..05263b6e 100644 --- a/shake256.c +++ b/shake256.c @@ -40,17 +40,13 @@ #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); } diff --git a/testsuite/eddsa-sign-test.c b/testsuite/eddsa-sign-test.c index 2ea1e4bd..1bc80c94 100644 --- a/testsuite/eddsa-sign-test.c +++ b/testsuite/eddsa-sign-test.c @@ -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); } diff --git a/testsuite/eddsa-verify-test.c b/testsuite/eddsa-verify-test.c index cc853a55..de850626 100644 --- a/testsuite/eddsa-verify-test.c +++ b/testsuite/eddsa-verify-test.c @@ -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); } diff --git a/testsuite/shake128-test.c b/testsuite/shake128-test.c index fd55b4b2..d1b71de9 100644 --- a/testsuite/shake128-test.c +++ b/testsuite/shake128-test.c @@ -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, diff --git a/testsuite/shake256-test.c b/testsuite/shake256-test.c index 93e1107e..9f5d9ced 100644 --- a/testsuite/shake256-test.c +++ b/testsuite/shake256-test.c @@ -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,