Add crypto_core_keccak1600_state, remove keccak1600_STATEBYTES

This commit is contained in:
Frank Denis
2026-01-06 23:00:21 +01:00
parent 4a1ff8bf03
commit 8a7378460f
17 changed files with 259 additions and 246 deletions
@@ -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);
}
@@ -214,43 +214,43 @@ sha3_256(unsigned char out[32], const unsigned char *in, size_t inlen)
static void
sha3_512(unsigned char out[64], const unsigned char *in, size_t inlen)
{
unsigned char state[200];
size_t offset = 0;
size_t consumed = 0;
size_t chunk_size;
unsigned char pad;
crypto_core_keccak1600_state state;
size_t offset = 0;
size_t consumed = 0;
size_t chunk_size;
unsigned char pad;
crypto_core_keccak1600_init(state);
crypto_core_keccak1600_init(&state);
while (consumed < inlen) {
if (offset == SHA3_512_RATE) {
crypto_core_keccak1600_permute_24(state);
crypto_core_keccak1600_permute_24(&state);
offset = 0;
}
chunk_size = SHA3_512_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 == SHA3_512_RATE) {
crypto_core_keccak1600_permute_24(state);
crypto_core_keccak1600_permute_24(&state);
offset = 0;
}
if (offset == SHA3_512_RATE - 1) {
pad = SHA3_DOMAIN | 0x80;
crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1);
crypto_core_keccak1600_xor_bytes(&state, &pad, offset, 1);
} else {
pad = SHA3_DOMAIN;
crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1);
crypto_core_keccak1600_xor_bytes(&state, &pad, offset, 1);
pad = 0x80;
crypto_core_keccak1600_xor_bytes(state, &pad, SHA3_512_RATE - 1, 1);
crypto_core_keccak1600_xor_bytes(&state, &pad, SHA3_512_RATE - 1, 1);
}
crypto_core_keccak1600_permute_24(state);
crypto_core_keccak1600_extract_bytes(state, out, 0, 64);
crypto_core_keccak1600_permute_24(&state);
crypto_core_keccak1600_extract_bytes(&state, out, 0, 64);
}
static void
@@ -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;
@@ -4,15 +4,17 @@
#include <stddef.h>
#include <stdint.h>
#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);
@@ -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;
@@ -4,15 +4,17 @@
#include <stddef.h>
#include <stdint.h>
#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);
@@ -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;
@@ -4,6 +4,8 @@
#include <stddef.h>
#include <stdint.h>
#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);
@@ -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;
@@ -4,6 +4,8 @@
#include <stddef.h>
#include <stdint.h>
#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);
@@ -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