From 6a892675bc6d0624ff158715548728eb068210a0 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 26 Nov 2025 23:00:42 +0100 Subject: [PATCH] SHAKE: if the rate is exactly full, process that block before padding --- src/libsodium/crypto_xof/shake128/ref/shake128_ref.c | 6 ++++++ src/libsodium/crypto_xof/shake256/ref/shake256_ref.c | 6 ++++++ .../crypto_xof/turboshake128/ref/turboshake128_ref.c | 6 ++++++ .../crypto_xof/turboshake256/ref/turboshake256_ref.c | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c index ac113725..a973618e 100644 --- a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c +++ b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c @@ -56,6 +56,12 @@ shake128_finalize(shake128_state_internal *state) { unsigned char pad; + /* If the rate is exactly full, process that block before padding */ + if (state->offset == SHAKE128_RATE) { + crypto_core_keccak1600_permute_24(state->state); + state->offset = 0; + } + /* Apply padding: domain byte at current position, 0x80 at last byte */ if (state->offset == SHAKE128_RATE - 1) { /* Special case: padding fits in one byte */ diff --git a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c index 1e1c1f64..af15e774 100644 --- a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c +++ b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c @@ -56,6 +56,12 @@ shake256_finalize(shake256_state_internal *state) { unsigned char pad; + /* If the rate is exactly full, process that block before padding */ + if (state->offset == SHAKE256_RATE) { + crypto_core_keccak1600_permute_24(state->state); + state->offset = 0; + } + /* Apply padding: domain byte at current position, 0x80 at last byte */ if (state->offset == SHAKE256_RATE - 1) { /* Special case: padding fits in one byte */ diff --git a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c index 3725456f..d16fc727 100644 --- a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c +++ b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c @@ -56,6 +56,12 @@ turboshake128_finalize(turboshake128_state_internal *state) { unsigned char pad; + /* If the rate is exactly full, process that block before padding */ + if (state->offset == TURBOSHAKE128_RATE) { + crypto_core_keccak1600_permute_12(state->state); + state->offset = 0; + } + /* Apply padding: domain byte at current position, 0x80 at last byte */ if (state->offset == TURBOSHAKE128_RATE - 1) { /* Special case: padding fits in one byte */ diff --git a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c index a7aa178b..b50fbf41 100644 --- a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c +++ b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c @@ -56,6 +56,12 @@ turboshake256_finalize(turboshake256_state_internal *state) { unsigned char pad; + /* If the rate is exactly full, process that block before padding */ + if (state->offset == TURBOSHAKE256_RATE) { + crypto_core_keccak1600_permute_12(state->state); + state->offset = 0; + } + /* Apply padding: domain byte at current position, 0x80 at last byte */ if (state->offset == TURBOSHAKE256_RATE - 1) { /* Special case: padding fits in one byte */