From d66b358741283d02a9f510d72a736eced166c90c Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 6 Jan 2026 23:00:11 +0100 Subject: [PATCH] Add crypto_core_keccak1600_state, remove keccak1600_STATEBYTES --- .../crypto_core/keccak1600/keccak1600.c | 24 +-- .../crypto_xof/shake128/ref/shake128_ref.c | 20 +-- .../crypto_xof/shake128/ref/shake128_ref.h | 10 +- .../crypto_xof/shake256/ref/shake256_ref.c | 20 +-- .../crypto_xof/shake256/ref/shake256_ref.h | 10 +- .../turboshake128/ref/turboshake128_ref.c | 20 +-- .../turboshake128/ref/turboshake128_ref.h | 10 +- .../turboshake256/ref/turboshake256_ref.c | 20 +-- .../turboshake256/ref/turboshake256_ref.h | 10 +- .../include/sodium/crypto_core_keccak1600.h | 38 +++-- test/default/core_keccak1600.c | 141 ++++++++---------- test/default/core_keccak1600.exp | 18 +-- test/default/xof_shake128.c | 34 ++--- test/default/xof_shake256.c | 34 ++--- test/default/xof_turboshake128.c | 34 ++--- test/default/xof_turboshake256.c | 34 ++--- 16 files changed, 245 insertions(+), 232 deletions(-) diff --git a/src/libsodium/crypto_core/keccak1600/keccak1600.c b/src/libsodium/crypto_core/keccak1600/keccak1600.c index ff9f73f6..d1eeadb4 100644 --- a/src/libsodium/crypto_core/keccak1600/keccak1600.c +++ b/src/libsodium/crypto_core/keccak1600/keccak1600.c @@ -4,37 +4,39 @@ size_t crypto_core_keccak1600_statebytes(void) { - return crypto_core_keccak1600_STATEBYTES; + return sizeof(crypto_core_keccak1600_state); } void -crypto_core_keccak1600_init(void *state) +crypto_core_keccak1600_init(crypto_core_keccak1600_state *state) { - keccak1600_ref_init(state); + keccak1600_ref_init(state->opaque); } void -crypto_core_keccak1600_xor_bytes(void *state, const unsigned char *bytes, size_t offset, +crypto_core_keccak1600_xor_bytes(crypto_core_keccak1600_state *state, + const unsigned char *bytes, size_t offset, size_t length) { - keccak1600_ref_xor_bytes(state, bytes, offset, length); + keccak1600_ref_xor_bytes(state->opaque, bytes, offset, length); } void -crypto_core_keccak1600_extract_bytes(const void *state, unsigned char *bytes, size_t offset, +crypto_core_keccak1600_extract_bytes(const crypto_core_keccak1600_state *state, + unsigned char *bytes, size_t offset, size_t length) { - keccak1600_ref_extract_bytes(state, bytes, offset, length); + keccak1600_ref_extract_bytes(state->opaque, bytes, offset, length); } void -crypto_core_keccak1600_permute_24(void *state) +crypto_core_keccak1600_permute_24(crypto_core_keccak1600_state *state) { - keccak1600_ref_permute_24(state); + keccak1600_ref_permute_24(state->opaque); } void -crypto_core_keccak1600_permute_12(void *state) +crypto_core_keccak1600_permute_12(crypto_core_keccak1600_state *state) { - keccak1600_ref_permute_12(state); + keccak1600_ref_permute_12(state->opaque); } diff --git a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c index fb0366e1..5df0f8d9 100644 --- a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c +++ b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c @@ -9,7 +9,7 @@ int shake128_ref_init_with_domain(shake128_state_internal *state, unsigned char domain) { - crypto_core_keccak1600_init(state->state); + crypto_core_keccak1600_init(&state->state); state->offset = 0; state->phase = SHAKE128_PHASE_ABSORBING; state->domain = domain; @@ -36,14 +36,14 @@ shake128_ref_update(shake128_state_internal *state, const unsigned char *in, siz while (consumed < inlen) { if (state->offset == SHAKE128_RATE) { - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; } chunk_size = SHAKE128_RATE - state->offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state->state, &in[consumed], state->offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size); state->offset += chunk_size; consumed += chunk_size; } @@ -58,7 +58,7 @@ shake128_finalize(shake128_state_internal *state) /* If the rate is exactly full, process that block before padding */ if (state->offset == SHAKE128_RATE) { - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; } @@ -66,16 +66,16 @@ shake128_finalize(shake128_state_internal *state) if (state->offset == SHAKE128_RATE - 1) { /* Special case: padding fits in one byte */ pad = (unsigned char) (state->domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state->state, &pad, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, state->offset, 1); } else { /* Normal case: domain and 0x80 at different positions */ - crypto_core_keccak1600_xor_bytes(state->state, &state->domain, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &state->domain, state->offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state->state, &pad, SHAKE128_RATE - 1, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, SHAKE128_RATE - 1, 1); } /* Final permutation */ - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; state->phase = SHAKE128_PHASE_SQUEEZING; @@ -93,14 +93,14 @@ shake128_ref_squeeze(shake128_state_internal *state, unsigned char *out, size_t while (extracted < outlen) { if (state->offset == SHAKE128_RATE) { - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; } chunk_size = SHAKE128_RATE - state->offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state->state, &out[extracted], state->offset, + crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset, chunk_size); state->offset += chunk_size; extracted += chunk_size; diff --git a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.h b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.h index 34021def..0969a83f 100644 --- a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.h +++ b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.h @@ -4,15 +4,17 @@ #include #include +#include "crypto_core_keccak1600.h" + #define SHAKE128_RATE 168 typedef enum { SHAKE128_PHASE_ABSORBING = 0, SHAKE128_PHASE_SQUEEZING = 1 } shake128_phase; typedef struct shake128_state_internal_ { - unsigned char state[200]; - size_t offset; - uint8_t phase; - unsigned char domain; /* Domain separation byte */ + crypto_core_keccak1600_state state; + size_t offset; + uint8_t phase; + unsigned char domain; } shake128_state_internal; int shake128_ref(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen); diff --git a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c index 7fe50a93..7b4b4909 100644 --- a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c +++ b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c @@ -9,7 +9,7 @@ int shake256_ref_init_with_domain(shake256_state_internal *state, unsigned char domain) { - crypto_core_keccak1600_init(state->state); + crypto_core_keccak1600_init(&state->state); state->offset = 0; state->phase = SHAKE256_PHASE_ABSORBING; state->domain = domain; @@ -36,14 +36,14 @@ shake256_ref_update(shake256_state_internal *state, const unsigned char *in, siz while (consumed < inlen) { if (state->offset == SHAKE256_RATE) { - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; } chunk_size = SHAKE256_RATE - state->offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state->state, &in[consumed], state->offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size); state->offset += chunk_size; consumed += chunk_size; } @@ -58,7 +58,7 @@ shake256_finalize(shake256_state_internal *state) /* If the rate is exactly full, process that block before padding */ if (state->offset == SHAKE256_RATE) { - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; } @@ -66,16 +66,16 @@ shake256_finalize(shake256_state_internal *state) if (state->offset == SHAKE256_RATE - 1) { /* Special case: padding fits in one byte */ pad = (unsigned char) (state->domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state->state, &pad, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, state->offset, 1); } else { /* Normal case: domain and 0x80 at different positions */ - crypto_core_keccak1600_xor_bytes(state->state, &state->domain, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &state->domain, state->offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state->state, &pad, SHAKE256_RATE - 1, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, SHAKE256_RATE - 1, 1); } /* Final permutation */ - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; state->phase = SHAKE256_PHASE_SQUEEZING; @@ -93,14 +93,14 @@ shake256_ref_squeeze(shake256_state_internal *state, unsigned char *out, size_t while (extracted < outlen) { if (state->offset == SHAKE256_RATE) { - crypto_core_keccak1600_permute_24(state->state); + crypto_core_keccak1600_permute_24(&state->state); state->offset = 0; } chunk_size = SHAKE256_RATE - state->offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state->state, &out[extracted], state->offset, + crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset, chunk_size); state->offset += chunk_size; extracted += chunk_size; diff --git a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.h b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.h index 69b03eab..7a3a03a1 100644 --- a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.h +++ b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.h @@ -4,15 +4,17 @@ #include #include +#include "crypto_core_keccak1600.h" + #define SHAKE256_RATE 136 typedef enum { SHAKE256_PHASE_ABSORBING = 0, SHAKE256_PHASE_SQUEEZING = 1 } shake256_phase; typedef struct shake256_state_internal_ { - unsigned char state[200]; - size_t offset; - uint8_t phase; - unsigned char domain; /* Domain separation byte */ + crypto_core_keccak1600_state state; + size_t offset; + uint8_t phase; + unsigned char domain; } shake256_state_internal; int shake256_ref(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen); diff --git a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c index 9d4dab27..0adc33c7 100644 --- a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c +++ b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c @@ -9,7 +9,7 @@ int turboshake128_ref_init_with_domain(turboshake128_state_internal *state, unsigned char domain) { - crypto_core_keccak1600_init(state->state); + crypto_core_keccak1600_init(&state->state); state->offset = 0; state->phase = TURBOSHAKE128_PHASE_ABSORBING; state->domain = domain; @@ -36,14 +36,14 @@ turboshake128_ref_update(turboshake128_state_internal *state, const unsigned cha while (consumed < inlen) { if (state->offset == TURBOSHAKE128_RATE) { - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; } chunk_size = TURBOSHAKE128_RATE - state->offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state->state, &in[consumed], state->offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size); state->offset += chunk_size; consumed += chunk_size; } @@ -58,7 +58,7 @@ turboshake128_finalize(turboshake128_state_internal *state) /* If the rate is exactly full, process that block before padding */ if (state->offset == TURBOSHAKE128_RATE) { - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; } @@ -66,16 +66,16 @@ turboshake128_finalize(turboshake128_state_internal *state) if (state->offset == TURBOSHAKE128_RATE - 1) { /* Special case: padding fits in one byte */ pad = (unsigned char) (state->domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state->state, &pad, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, state->offset, 1); } else { /* Normal case: domain and 0x80 at different positions */ - crypto_core_keccak1600_xor_bytes(state->state, &state->domain, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &state->domain, state->offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state->state, &pad, TURBOSHAKE128_RATE - 1, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, TURBOSHAKE128_RATE - 1, 1); } /* Final permutation (12 rounds for TurboSHAKE) */ - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; state->phase = TURBOSHAKE128_PHASE_SQUEEZING; @@ -93,14 +93,14 @@ turboshake128_ref_squeeze(turboshake128_state_internal *state, unsigned char *ou while (extracted < outlen) { if (state->offset == TURBOSHAKE128_RATE) { - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; } chunk_size = TURBOSHAKE128_RATE - state->offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state->state, &out[extracted], state->offset, + crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset, chunk_size); state->offset += chunk_size; extracted += chunk_size; diff --git a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.h b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.h index 30c5acd8..c1322a2d 100644 --- a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.h +++ b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.h @@ -4,6 +4,8 @@ #include #include +#include "crypto_core_keccak1600.h" + #define TURBOSHAKE128_RATE 168 typedef enum { @@ -12,10 +14,10 @@ typedef enum { } turboshake128_phase; typedef struct turboshake128_state_internal_ { - unsigned char state[200]; - size_t offset; - uint8_t phase; - unsigned char domain; /* Domain separation byte */ + crypto_core_keccak1600_state state; + size_t offset; + uint8_t phase; + unsigned char domain; } turboshake128_state_internal; int turboshake128_ref(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen); diff --git a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c index f648a7fa..4193ae71 100644 --- a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c +++ b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c @@ -9,7 +9,7 @@ int turboshake256_ref_init_with_domain(turboshake256_state_internal *state, unsigned char domain) { - crypto_core_keccak1600_init(state->state); + crypto_core_keccak1600_init(&state->state); state->offset = 0; state->phase = TURBOSHAKE256_PHASE_ABSORBING; state->domain = domain; @@ -36,14 +36,14 @@ turboshake256_ref_update(turboshake256_state_internal *state, const unsigned cha while (consumed < inlen) { if (state->offset == TURBOSHAKE256_RATE) { - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; } chunk_size = TURBOSHAKE256_RATE - state->offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state->state, &in[consumed], state->offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size); state->offset += chunk_size; consumed += chunk_size; } @@ -58,7 +58,7 @@ turboshake256_finalize(turboshake256_state_internal *state) /* If the rate is exactly full, process that block before padding */ if (state->offset == TURBOSHAKE256_RATE) { - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; } @@ -66,16 +66,16 @@ turboshake256_finalize(turboshake256_state_internal *state) if (state->offset == TURBOSHAKE256_RATE - 1) { /* Special case: padding fits in one byte */ pad = (unsigned char) (state->domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state->state, &pad, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, state->offset, 1); } else { /* Normal case: domain and 0x80 at different positions */ - crypto_core_keccak1600_xor_bytes(state->state, &state->domain, state->offset, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &state->domain, state->offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state->state, &pad, TURBOSHAKE256_RATE - 1, 1); + crypto_core_keccak1600_xor_bytes(&state->state, &pad, TURBOSHAKE256_RATE - 1, 1); } /* Final permutation (12 rounds for TurboSHAKE) */ - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; state->phase = TURBOSHAKE256_PHASE_SQUEEZING; @@ -93,14 +93,14 @@ turboshake256_ref_squeeze(turboshake256_state_internal *state, unsigned char *ou while (extracted < outlen) { if (state->offset == TURBOSHAKE256_RATE) { - crypto_core_keccak1600_permute_12(state->state); + crypto_core_keccak1600_permute_12(&state->state); state->offset = 0; } chunk_size = TURBOSHAKE256_RATE - state->offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state->state, &out[extracted], state->offset, + crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset, chunk_size); state->offset += chunk_size; extracted += chunk_size; diff --git a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.h b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.h index d154f24b..d7320757 100644 --- a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.h +++ b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.h @@ -4,6 +4,8 @@ #include #include +#include "crypto_core_keccak1600.h" + #define TURBOSHAKE256_RATE 136 typedef enum { @@ -12,10 +14,10 @@ typedef enum { } turboshake256_phase; typedef struct turboshake256_state_internal_ { - unsigned char state[200]; - size_t offset; - uint8_t phase; - unsigned char domain; /* Domain separation byte */ + crypto_core_keccak1600_state state; + size_t offset; + uint8_t phase; + unsigned char domain; } turboshake256_state_internal; int turboshake256_ref(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen); diff --git a/src/libsodium/include/sodium/crypto_core_keccak1600.h b/src/libsodium/include/sodium/crypto_core_keccak1600.h index 1c84c720..46e35ac8 100644 --- a/src/libsodium/include/sodium/crypto_core_keccak1600.h +++ b/src/libsodium/include/sodium/crypto_core_keccak1600.h @@ -12,35 +12,51 @@ extern "C" { #endif -#define crypto_core_keccak1600_STATEBYTES 200U +#ifdef __IBMC__ +# pragma pack(1) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack(1) +#else +# pragma pack(push, 1) +#endif + +typedef struct CRYPTO_ALIGN(16) crypto_core_keccak1600_state { + unsigned char opaque[224]; +} crypto_core_keccak1600_state; + +#ifdef __IBMC__ +# pragma pack(pop) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack() +#else +# pragma pack(pop) +#endif + SODIUM_EXPORT size_t crypto_core_keccak1600_statebytes(void); -/* Initialize state to all zeros */ SODIUM_EXPORT -void crypto_core_keccak1600_init(void *state) +void crypto_core_keccak1600_init(crypto_core_keccak1600_state *state) __attribute__ ((nonnull)); -/* XOR bytes into state (for absorbing) */ SODIUM_EXPORT -void crypto_core_keccak1600_xor_bytes(void *state, const unsigned char *bytes, +void crypto_core_keccak1600_xor_bytes(crypto_core_keccak1600_state *state, + const unsigned char *bytes, size_t offset, size_t length) __attribute__ ((nonnull)); -/* Extract bytes from state (for squeezing) */ SODIUM_EXPORT -void crypto_core_keccak1600_extract_bytes(const void *state, unsigned char *bytes, +void crypto_core_keccak1600_extract_bytes(const crypto_core_keccak1600_state *state, + unsigned char *bytes, size_t offset, size_t length) __attribute__ ((nonnull)); -/* Keccak-f[1600]: 24 rounds (for SHAKE) */ SODIUM_EXPORT -void crypto_core_keccak1600_permute_24(void *state) +void crypto_core_keccak1600_permute_24(crypto_core_keccak1600_state *state) __attribute__ ((nonnull)); -/* Keccak-p[1600,12]: 12 rounds (for TurboSHAKE) */ SODIUM_EXPORT -void crypto_core_keccak1600_permute_12(void *state) +void crypto_core_keccak1600_permute_12(crypto_core_keccak1600_state *state) __attribute__ ((nonnull)); #ifdef __cplusplus diff --git a/test/default/core_keccak1600.c b/test/default/core_keccak1600.c index 08f926a0..2377c32f 100644 --- a/test/default/core_keccak1600.c +++ b/test/default/core_keccak1600.c @@ -40,15 +40,15 @@ compare_states(const char *label, const unsigned char *actual, const unsigned ch int main(void) { - unsigned char state[crypto_core_keccak1600_STATEBYTES]; - unsigned char extracted[64]; - unsigned char test_data[64]; - unsigned char sentinel[64]; - unsigned char state_12[200], state_24[200]; - unsigned char last_byte; - size_t i; - int test_failures = 0; - int differs; + crypto_core_keccak1600_state state; + unsigned char extracted[64]; + unsigned char test_data[64]; + unsigned char sentinel[64]; + crypto_core_keccak1600_state state_12, state_24; + unsigned char last_byte; + size_t i; + int test_failures = 0; + int differs; /* Test vectors for Keccak-f[1600] (24 rounds) */ /* Test vector 1: All-zero input for Keccak-f[1600] */ @@ -125,47 +125,40 @@ main(void) printf("=== Keccak-1600 Core Function Tests ===\n\n"); - /* Basic API tests */ - printf("Test 1: API constants\n"); - printf(" statebytes: %u\n", (unsigned int) crypto_core_keccak1600_statebytes()); - assert(crypto_core_keccak1600_statebytes() == crypto_core_keccak1600_STATEBYTES); - assert(crypto_core_keccak1600_STATEBYTES == 200U); - printf(" PASS: statebytes = 200\n\n"); - - /* Test 2: Init function */ - printf("Test 2: crypto_core_keccak1600_init\n"); - memset(state, 0xFF, sizeof state); - crypto_core_keccak1600_init(state); - for (i = 0; i < crypto_core_keccak1600_STATEBYTES; i++) { - if (state[i] != 0) { + /* Test 1: Init function */ + printf("Test 1: crypto_core_keccak1600_init\n"); + memset(state.opaque, 0xFF, 200); + crypto_core_keccak1600_init(&state); + for (i = 0; i < 200; i++) { + if (state.opaque[i] != 0) { printf(" FAIL: State not zeroed at byte %u\n", (unsigned int) i); test_failures++; break; } } - if (i == crypto_core_keccak1600_STATEBYTES) { + if (i == 200) { printf(" PASS: State initialized to zeros\n\n"); } - /* Test 3: XOR and extract functions */ - printf("Test 3: crypto_core_keccak1600_xor_bytes and extract_bytes\n"); - crypto_core_keccak1600_init(state); + /* Test 2: XOR and extract functions */ + printf("Test 2: crypto_core_keccak1600_xor_bytes and extract_bytes\n"); + crypto_core_keccak1600_init(&state); for (i = 0; i < sizeof test_data; i++) { test_data[i] = (unsigned char) i; } /* Edge case: zero-length XOR/extract should be a no-op (test at offset 0 and at end) */ { - static const size_t offsets[] = { 0, crypto_core_keccak1600_STATEBYTES }; + static const size_t offsets[] = { 0, 200 }; size_t t; for (t = 0; t < sizeof offsets / sizeof offsets[0]; t++) { - crypto_core_keccak1600_init(state); + crypto_core_keccak1600_init(&state); memset(extracted, 0xA5, sizeof extracted); memset(sentinel, 0xA5, sizeof sentinel); - crypto_core_keccak1600_xor_bytes(state, test_data, offsets[t], 0); - crypto_core_keccak1600_extract_bytes(state, extracted, offsets[t], 0); - for (i = 0; i < sizeof state; i++) { - if (state[i] != 0) { + crypto_core_keccak1600_xor_bytes(&state, test_data, offsets[t], 0); + crypto_core_keccak1600_extract_bytes(&state, extracted, offsets[t], 0); + for (i = 0; i < 200; i++) { + if (state.opaque[i] != 0) { printf(" FAIL: XOR length 0 at offset %u modified state\n\n", (unsigned) offsets[t]); test_failures++; @@ -181,21 +174,19 @@ main(void) } /* Edge case: XOR/extract last byte */ - crypto_core_keccak1600_init(state); + crypto_core_keccak1600_init(&state); memset(extracted, 0, sizeof extracted); last_byte = 0x5A; - crypto_core_keccak1600_xor_bytes(state, &last_byte, - crypto_core_keccak1600_STATEBYTES - 1, 1); - crypto_core_keccak1600_extract_bytes(state, extracted, - crypto_core_keccak1600_STATEBYTES - 1, 1); + crypto_core_keccak1600_xor_bytes(&state, &last_byte, 199, 1); + crypto_core_keccak1600_extract_bytes(&state, extracted, 199, 1); if (extracted[0] != last_byte) { printf(" FAIL: XOR/extract last byte mismatch\n\n"); test_failures++; } - crypto_core_keccak1600_init(state); - crypto_core_keccak1600_xor_bytes(state, test_data, 0, sizeof test_data); - crypto_core_keccak1600_extract_bytes(state, extracted, 0, sizeof test_data); + crypto_core_keccak1600_init(&state); + crypto_core_keccak1600_xor_bytes(&state, test_data, 0, sizeof test_data); + crypto_core_keccak1600_extract_bytes(&state, extracted, 0, sizeof test_data); if (memcmp(extracted, test_data, sizeof test_data) == 0) { printf(" PASS: XOR and extract work correctly\n\n"); } else { @@ -203,40 +194,40 @@ main(void) test_failures++; } - /* Test 4: Keccak-f[1600] with all-zero input (24 rounds) */ - printf("Test 4: Keccak-f[1600] (24 rounds) - Zero input\n"); - memcpy(state, keccak_f_1600_zero_input, 200); - crypto_core_keccak1600_permute_24(state); + /* Test 3: Keccak-f[1600] with all-zero input (24 rounds) */ + printf("Test 3: Keccak-f[1600] (24 rounds) - Zero input\n"); + memcpy(state.opaque, keccak_f_1600_zero_input, 200); + crypto_core_keccak1600_permute_24(&state); test_failures += - compare_states(" Keccak-f[1600] zero", state, keccak_f_1600_zero_expected, 200); + compare_states(" Keccak-f[1600] zero", state.opaque, keccak_f_1600_zero_expected, 200); printf("\n"); - /* Test 5: Keccak-f[1600] with pattern input (24 rounds) */ - printf("Test 5: Keccak-f[1600] (24 rounds) - Pattern 0xa3 input\n"); - memcpy(state, keccak_f_1600_pattern_input, 200); - crypto_core_keccak1600_permute_24(state); + /* Test 4: Keccak-f[1600] with pattern input (24 rounds) */ + printf("Test 4: Keccak-f[1600] (24 rounds) - Pattern 0xa3 input\n"); + memcpy(state.opaque, keccak_f_1600_pattern_input, 200); + crypto_core_keccak1600_permute_24(&state); test_failures += - compare_states(" Keccak-f[1600] pattern", state, keccak_f_1600_pattern_expected, 200); + compare_states(" Keccak-f[1600] pattern", state.opaque, keccak_f_1600_pattern_expected, 200); printf("\n"); - /* Test 6: Keccak-p[1600,12] with all-zero input (12 rounds) */ - printf("Test 6: Keccak-p[1600,12] (12 rounds) - Zero input\n"); - crypto_core_keccak1600_init(state); - crypto_core_keccak1600_permute_12(state); + /* Test 5: Keccak-p[1600,12] with all-zero input (12 rounds) */ + printf("Test 5: Keccak-p[1600,12] (12 rounds) - Zero input\n"); + crypto_core_keccak1600_init(&state); + crypto_core_keccak1600_permute_12(&state); test_failures += - compare_states(" Keccak-p[1600,12] zero", state, keccak_p_12_zero_expected, 200); + compare_states(" Keccak-p[1600,12] zero", state.opaque, keccak_p_12_zero_expected, 200); printf("\n"); - /* Test 7: Verify 12 and 24 rounds produce different outputs */ - printf("Test 7: Verify 12-round and 24-round differ\n"); - crypto_core_keccak1600_init(state_12); - crypto_core_keccak1600_init(state_24); - crypto_core_keccak1600_permute_12(state_12); - crypto_core_keccak1600_permute_24(state_24); + /* Test 6: Verify 12 and 24 rounds produce different outputs */ + printf("Test 6: Verify 12-round and 24-round differ\n"); + crypto_core_keccak1600_init(&state_12); + crypto_core_keccak1600_init(&state_24); + crypto_core_keccak1600_permute_12(&state_12); + crypto_core_keccak1600_permute_24(&state_24); differs = 0; for (i = 0; i < 200; i++) { - if (state_12[i] != state_24[i]) { + if (state_12.opaque[i] != state_24.opaque[i]) { differs = 1; break; } @@ -244,27 +235,27 @@ main(void) if (differs) { printf(" PASS: 12-round and 24-round produce different outputs\n"); printf(" First difference at byte %u: 12-round=0x%02x, 24-round=0x%02x\n\n", - (unsigned int) i, state_12[i], state_24[i]); + (unsigned int) i, state_12.opaque[i], state_24.opaque[i]); } else { printf(" FAIL: 12-round and 24-round produce identical outputs\n\n"); test_failures++; } - /* Test 8: Multiple permutations */ - printf("Test 8: Double permutation consistency\n"); - crypto_core_keccak1600_init(state); - crypto_core_keccak1600_permute_24(state); - memcpy(state_24, state, 200); - crypto_core_keccak1600_permute_24(state); + /* Test 7: Multiple permutations */ + printf("Test 7: Double permutation consistency\n"); + crypto_core_keccak1600_init(&state); + crypto_core_keccak1600_permute_24(&state); + memcpy(state_24.opaque, state.opaque, 200); + crypto_core_keccak1600_permute_24(&state); printf(" After 24+24 rounds: "); - print_hex("", state, 32); + print_hex("", state.opaque, 32); - crypto_core_keccak1600_init(state); - crypto_core_keccak1600_permute_12(state); - memcpy(state_12, state, 200); - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_init(&state); + crypto_core_keccak1600_permute_12(&state); + memcpy(state_12.opaque, state.opaque, 200); + crypto_core_keccak1600_permute_12(&state); printf(" After 12+12 rounds: "); - print_hex("", state, 32); + print_hex("", state.opaque, 32); printf("\n"); /* Final summary */ diff --git a/test/default/core_keccak1600.exp b/test/default/core_keccak1600.exp index 6660f0db..288f727b 100644 --- a/test/default/core_keccak1600.exp +++ b/test/default/core_keccak1600.exp @@ -1,29 +1,25 @@ === Keccak-1600 Core Function Tests === -Test 1: API constants - statebytes: 200 - PASS: statebytes = 200 - -Test 2: crypto_core_keccak1600_init +Test 1: crypto_core_keccak1600_init PASS: State initialized to zeros -Test 3: crypto_core_keccak1600_xor_bytes and extract_bytes +Test 2: crypto_core_keccak1600_xor_bytes and extract_bytes PASS: XOR and extract work correctly -Test 4: Keccak-f[1600] (24 rounds) - Zero input +Test 3: Keccak-f[1600] (24 rounds) - Zero input PASS: Keccak-f[1600] zero -Test 5: Keccak-f[1600] (24 rounds) - Pattern 0xa3 input +Test 4: Keccak-f[1600] (24 rounds) - Pattern 0xa3 input PASS: Keccak-f[1600] pattern -Test 6: Keccak-p[1600,12] (12 rounds) - Zero input +Test 5: Keccak-p[1600,12] (12 rounds) - Zero input PASS: Keccak-p[1600,12] zero -Test 7: Verify 12-round and 24-round differ +Test 6: Verify 12-round and 24-round differ PASS: 12-round and 24-round produce different outputs First difference at byte 0: 12-round=0x17, 24-round=0xe7 -Test 8: Double permutation consistency +Test 7: Double permutation consistency After 24+24 rounds: 3ccb6ef94d955c2d6db55770d02c336a6c6bd770128d3d0994d06955b2d9208a After 12+12 rounds: 048cbb36dc66034bc96a2de69835165f46e73b55de051b436c7a6154c9469f48 diff --git a/test/default/xof_shake128.c b/test/default/xof_shake128.c index dc21b057..bb2372d1 100644 --- a/test/default/xof_shake128.c +++ b/test/default/xof_shake128.c @@ -13,57 +13,57 @@ static void shake128_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, unsigned char domain) { - unsigned char state[crypto_core_keccak1600_STATEBYTES]; - size_t rate = crypto_xof_shake128_blockbytes(); - size_t offset = 0; - size_t consumed = 0; - size_t chunk_size; - size_t extracted = 0; - unsigned char pad; + crypto_core_keccak1600_state state; + size_t rate = crypto_xof_shake128_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; - crypto_core_keccak1600_init(state); + crypto_core_keccak1600_init(&state); while (consumed < inlen) { if (offset == rate) { - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state, &in[consumed], offset, chunk_size); offset += chunk_size; consumed += chunk_size; } if (offset == rate) { - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; } if (offset == rate - 1) { pad = (unsigned char) (domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, offset, 1); } else { - crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &domain, offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, rate - 1, 1); } - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; while (extracted < outlen) { if (offset == rate) { - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + crypto_core_keccak1600_extract_bytes(&state, &out[extracted], offset, chunk_size); offset += chunk_size; extracted += chunk_size; } diff --git a/test/default/xof_shake256.c b/test/default/xof_shake256.c index d5bf3a5a..4d709669 100644 --- a/test/default/xof_shake256.c +++ b/test/default/xof_shake256.c @@ -13,57 +13,57 @@ static void shake256_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, unsigned char domain) { - unsigned char state[crypto_core_keccak1600_STATEBYTES]; - size_t rate = crypto_xof_shake256_blockbytes(); - size_t offset = 0; - size_t consumed = 0; - size_t chunk_size; - size_t extracted = 0; - unsigned char pad; + crypto_core_keccak1600_state state; + size_t rate = crypto_xof_shake256_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; - crypto_core_keccak1600_init(state); + crypto_core_keccak1600_init(&state); while (consumed < inlen) { if (offset == rate) { - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state, &in[consumed], offset, chunk_size); offset += chunk_size; consumed += chunk_size; } if (offset == rate) { - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; } if (offset == rate - 1) { pad = (unsigned char) (domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, offset, 1); } else { - crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &domain, offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, rate - 1, 1); } - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; while (extracted < outlen) { if (offset == rate) { - crypto_core_keccak1600_permute_24(state); + crypto_core_keccak1600_permute_24(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + crypto_core_keccak1600_extract_bytes(&state, &out[extracted], offset, chunk_size); offset += chunk_size; extracted += chunk_size; } diff --git a/test/default/xof_turboshake128.c b/test/default/xof_turboshake128.c index 82c5147a..27380019 100644 --- a/test/default/xof_turboshake128.c +++ b/test/default/xof_turboshake128.c @@ -13,57 +13,57 @@ static void turboshake128_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, unsigned char domain) { - unsigned char state[crypto_core_keccak1600_STATEBYTES]; - size_t rate = crypto_xof_turboshake128_blockbytes(); - size_t offset = 0; - size_t consumed = 0; - size_t chunk_size; - size_t extracted = 0; - unsigned char pad; + crypto_core_keccak1600_state state; + size_t rate = crypto_xof_turboshake128_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; - crypto_core_keccak1600_init(state); + crypto_core_keccak1600_init(&state); while (consumed < inlen) { if (offset == rate) { - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state, &in[consumed], offset, chunk_size); offset += chunk_size; consumed += chunk_size; } if (offset == rate) { - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; } if (offset == rate - 1) { pad = (unsigned char) (domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, offset, 1); } else { - crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &domain, offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, rate - 1, 1); } - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; while (extracted < outlen) { if (offset == rate) { - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + crypto_core_keccak1600_extract_bytes(&state, &out[extracted], offset, chunk_size); offset += chunk_size; extracted += chunk_size; } diff --git a/test/default/xof_turboshake256.c b/test/default/xof_turboshake256.c index e8039be3..e8f22b4e 100644 --- a/test/default/xof_turboshake256.c +++ b/test/default/xof_turboshake256.c @@ -13,57 +13,57 @@ static void turboshake256_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, unsigned char domain) { - unsigned char state[crypto_core_keccak1600_STATEBYTES]; - size_t rate = crypto_xof_turboshake256_blockbytes(); - size_t offset = 0; - size_t consumed = 0; - size_t chunk_size; - size_t extracted = 0; - unsigned char pad; + crypto_core_keccak1600_state state; + size_t rate = crypto_xof_turboshake256_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; - crypto_core_keccak1600_init(state); + crypto_core_keccak1600_init(&state); while (consumed < inlen) { if (offset == rate) { - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > inlen - consumed) { chunk_size = inlen - consumed; } - crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + crypto_core_keccak1600_xor_bytes(&state, &in[consumed], offset, chunk_size); offset += chunk_size; consumed += chunk_size; } if (offset == rate) { - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; } if (offset == rate - 1) { pad = (unsigned char) (domain ^ 0x80); - crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, offset, 1); } else { - crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + crypto_core_keccak1600_xor_bytes(&state, &domain, offset, 1); pad = 0x80; - crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + crypto_core_keccak1600_xor_bytes(&state, &pad, rate - 1, 1); } - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; while (extracted < outlen) { if (offset == rate) { - crypto_core_keccak1600_permute_12(state); + crypto_core_keccak1600_permute_12(&state); offset = 0; } chunk_size = rate - offset; if (chunk_size > outlen - extracted) { chunk_size = outlen - extracted; } - crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + crypto_core_keccak1600_extract_bytes(&state, &out[extracted], offset, chunk_size); offset += chunk_size; extracted += chunk_size; }