Add crypto_core_keccak1600_state, remove keccak1600_STATEBYTES

This commit is contained in:
Frank Denis
2026-01-06 15:42:08 +01:00
parent fa79f073ad
commit d66b358741
16 changed files with 245 additions and 232 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);
}
@@ -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
+66 -75
View File
@@ -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 */
+7 -11
View File
@@ -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
+17 -17
View File
@@ -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;
}
+17 -17
View File
@@ -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;
}
+17 -17
View File
@@ -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;
}
+17 -17
View File
@@ -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;
}