lists.lysator.liu.se
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
List overview
Download
nettle-bugs
April 2025
----- 2025 -----
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
nettle-bugs@lists.lysator.liu.se
1 participants
1 discussions
Start a n
N
ew thread
Trimming sha3 context struct
by Niels Möller
13 May '25
13 May '25
Hi, I recently realized that unlike other hash functions in Nettle, we can do without the block size buffer for sha3. Below patch reduces the buffer to just 8 bytes, since input can be xored directly to the state array (with the extra 8-byte buffer used for partial words on big endian platforms), and similarly, shake output can ge generated from the state array. The implementation of _update and _shake_output becomes a bit more complex, with separate code for big and little endian platforms.
…
[View More]
I had expected a minor speedup for little-endian, but I haven't seen any significant performance changes on my x86_64 machine. Before, the size of the context structs ranged from 280 bytes for sha3_512 to 352 bytes for sha3_224 and 376 for shake128. After these changes, all variants use the same context struct of 216 bytes. One can then eliminate the different struct sha3_*_ctx, replacing with a single struct sha3_ctx, and similarly only a single sha3_init function. Would it be useful to keep old names as preprocessor aliases? Either by default, or via a separate header nettle/sha3-compat.h? Regards, /Niels --------------8<--------- 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 <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 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 <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); } 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 <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); } 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 <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); } 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 <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); } 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; + index = block_bytes; + ctx->shake_flag = 1; } - else - index = ~index; - assert (index <= block_size); + assert (index <= block_bytes); + { +#if WORDS_BIGENDIAN + unsigned byte_index = index & 7; - /* Write remaining data from the buffer. */ - left = block_size - index; + if (byte_index) + { + unsigned left = 8 - byte_index; if (length <= left) { - memcpy (dst, block + index, length); - return ~(index + length); + 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, block + index, left); + memcpy (dst, ((const uint8_t *) ctx->state.a) + index, left); length -= left; dst += left; } /* Write full blocks. */ - while (length > block_size) + for (; length > block_bytes; length -= block_bytes, dst += block_bytes) { - 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_bytes, dst, ctx->state.a); } - sha3_permute (state); - /* Fill in the buffer for next call. */ - _nettle_write_le64 (block_size, block, state->a); - memcpy (dst, block, length); - return ~length; + 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 <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; - if (pos > 0) + ctx->state.a[index++] ^= nettle_bswap64 (ctx->block.u64); + if (index == block_size) { - MD_FILL_OR_RETURN_INDEX (block_size, block, pos, length, data); - sha3_absorb (state, block_size, block); + sha3_permute (&ctx->state); + index = 0; + } } - for (; length >= block_size; length -= block_size, data += block_size) - sha3_absorb (state, block_size, data); - memcpy (block, data, length); - return length; + for (; length >= 8; length -= 8, data += 8) + { + 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) + { + 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 <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); } 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, -- Niels Möller. PGP key CB4962D070D77D7FCB8BA36271D8F1FF368C6677. Internet email is subject to wholesale government surveillance.
[View Less]
2
2
0
0
Results per page:
10
25
50
100
200