Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions mldsa/src/fips202/fips202.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ __contract__(
static void keccak_finalize(uint64_t s[MLD_KECCAK_LANES], unsigned int pos,
unsigned int r, uint8_t p)
__contract__(
requires(pos <= r && r < sizeof(uint64_t) * MLD_KECCAK_LANES)
requires(pos < r && r < sizeof(uint64_t) * MLD_KECCAK_LANES)
requires((r / 8) >= 1)
requires(memory_no_alias(s, sizeof(uint64_t) * MLD_KECCAK_LANES))
assigns(memory_slice(s, sizeof(uint64_t) * MLD_KECCAK_LANES))
Expand Down Expand Up @@ -142,7 +142,7 @@ __contract__(
requires((r == SHAKE128_RATE && pos <= SHAKE128_RATE) ||
(r == SHAKE256_RATE && pos <= SHAKE256_RATE) ||
(r == SHA3_512_RATE && pos <= SHA3_512_RATE))
requires(outlen <= 8 * r /* somewhat arbitrary bound */)
requires(outlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(s, sizeof(uint64_t) * MLD_KECCAK_LANES))
requires(memory_no_alias(out, outlen))
assigns(memory_slice(s, sizeof(uint64_t) * MLD_KECCAK_LANES))
Expand Down Expand Up @@ -202,7 +202,10 @@ void mld_shake128_absorb(mld_shake128ctx *state, const uint8_t *in,
MLD_INTERNAL_API
void mld_shake128_finalize(mld_shake128ctx *state)
{
keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F);
if (state->pos < SHAKE128_RATE)
{
keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F);
}
state->pos = SHAKE128_RATE;
}

Expand Down Expand Up @@ -236,7 +239,10 @@ void mld_shake256_absorb(mld_shake256ctx *state, const uint8_t *in,
MLD_INTERNAL_API
void mld_shake256_finalize(mld_shake256ctx *state)
{
keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F);
if (state->pos < SHAKE256_RATE)
{
keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F);
}
state->pos = SHAKE256_RATE;
}

Expand Down
16 changes: 9 additions & 7 deletions mldsa/src/fips202/fips202.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ __contract__(

#define mld_shake128_finalize MLD_NAMESPACE(shake128_finalize)
/**
* Concludes the absorb phase of the SHAKE128 XOF.
* Concludes the absorb phase of the SHAKE128 XOF. Repeated calls on an
* already-finalized state leave it unchanged.
*
* @param[in,out] state Pointer to state.
*/
Expand All @@ -79,7 +80,7 @@ __contract__(
requires(memory_no_alias(state, sizeof(mld_shake128ctx)))
requires(state->pos <= SHAKE128_RATE)
assigns(memory_slice(state, sizeof(mld_shake128ctx)))
ensures(state->pos <= SHAKE128_RATE)
ensures(state->pos == SHAKE128_RATE)
);

#define mld_shake128_squeeze MLD_NAMESPACE(shake128_squeeze)
Expand All @@ -94,7 +95,7 @@ __contract__(
MLD_INTERNAL_API
void mld_shake128_squeeze(uint8_t *out, size_t outlen, mld_shake128ctx *state)
__contract__(
requires(outlen <= 8 * SHAKE128_RATE /* somewhat arbitrary bound */)
requires(outlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(state, sizeof(mld_shake128ctx)))
requires(memory_no_alias(out, outlen))
requires(state->pos <= SHAKE128_RATE)
Expand Down Expand Up @@ -153,7 +154,8 @@ __contract__(

#define mld_shake256_finalize MLD_NAMESPACE(shake256_finalize)
/**
* Concludes the absorb phase of the SHAKE256 XOF.
* Concludes the absorb phase of the SHAKE256 XOF. Repeated calls on an
* already-finalized state leave it unchanged.
*
* @param[in,out] state Pointer to state.
*/
Expand All @@ -163,7 +165,7 @@ __contract__(
requires(memory_no_alias(state, sizeof(mld_shake256ctx)))
requires(state->pos <= SHAKE256_RATE)
assigns(memory_slice(state, sizeof(mld_shake256ctx)))
ensures(state->pos <= SHAKE256_RATE)
ensures(state->pos == SHAKE256_RATE)
);

#define mld_shake256_squeeze MLD_NAMESPACE(shake256_squeeze)
Expand All @@ -178,7 +180,7 @@ __contract__(
MLD_INTERNAL_API
void mld_shake256_squeeze(uint8_t *out, size_t outlen, mld_shake256ctx *state)
__contract__(
requires(outlen <= 8 * SHAKE256_RATE /* somewhat arbitrary bound */)
requires(outlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(state, sizeof(mld_shake256ctx)))
requires(memory_no_alias(out, outlen))
requires(state->pos <= SHAKE256_RATE)
Expand Down Expand Up @@ -214,7 +216,7 @@ MLD_INTERNAL_API
void mld_shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
__contract__(
requires(inlen <= MLD_MAX_BUFFER_SIZE)
requires(outlen <= 8 * SHAKE256_RATE /* somewhat arbitrary bound */)
requires(outlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(in, inlen))
requires(memory_no_alias(out, outlen))
assigns(memory_slice(out, outlen))
Expand Down
1 change: 1 addition & 0 deletions mldsa/src/fips202/fips202x4.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ static void mld_keccak_squeezeblocks_x4(uint8_t *out0, uint8_t *out1,
uint8_t *out2, uint8_t *out3,
size_t nblocks, uint64_t *s, unsigned r)
__contract__(
requires(r > 0)
requires(r <= sizeof(uint64_t) * MLD_KECCAK_LANES)
requires(nblocks <= 8 /* somewhat arbitrary bound */)
requires(memory_no_alias(s, sizeof(uint64_t) * MLD_KECCAK_LANES * MLD_KECCAK_WAY))
Expand Down
2 changes: 1 addition & 1 deletion mldsa/src/fips202/fips202x4.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ typedef struct
typedef struct
{
uint64_t ctx[MLD_KECCAK_LANES *
MLD_KECCAK_WAY]; /**< Interleaved 4-way Keccak state. */
MLD_KECCAK_WAY]; /**< 4-way Keccak state, stored sequentially. */
} mld_shake256x4ctx;

#if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
Expand Down
72 changes: 72 additions & 0 deletions test/src/test_unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string.h>
#include "../notrandombytes/notrandombytes.h"

#include "../../mldsa/src/fips202/fips202.h"
#include "../../mldsa/src/fips202/keccakf1600.h"
#include "../../mldsa/src/poly.h"
#include "../../mldsa/src/poly_kl.h"
Expand Down Expand Up @@ -64,6 +65,75 @@ unsigned int mld_rej_eta_c(int32_t *a, unsigned int target, unsigned int offset,
#endif
void mld_keccakf1600_permute_c(uint64_t *state);

static void fill_shake_input(uint8_t *input, size_t inlen, unsigned int round)
{
size_t i;

for (i = 0; i < inlen; i++)
{
input[i] = (uint8_t)((19 * i + 43 * round + (i >> 2)) & 0xFF);
}
}

static int test_shake_finalize_idempotent(void)
{
static const size_t input_lengths[] = {0,
1,
SHAKE256_RATE - 1,
SHAKE256_RATE,
SHAKE128_RATE - 1,
SHAKE128_RATE,
SHAKE128_RATE + 1};
uint8_t input[SHAKE128_RATE + 1];
uint8_t once[2 * SHAKE128_RATE];
uint8_t twice[2 * SHAKE128_RATE];
mld_shake128ctx shake128_once;
mld_shake128ctx shake128_twice;
mld_shake256ctx shake256_once;
mld_shake256ctx shake256_twice;
size_t round;

for (round = 0; round < sizeof(input_lengths) / sizeof(input_lengths[0]);
round++)
{
fill_shake_input(input, input_lengths[round], (unsigned int)round);

memset(once, 0, sizeof(once));
memset(twice, 0, sizeof(twice));
mld_shake128_init(&shake128_once);
mld_shake128_absorb(&shake128_once, input, input_lengths[round]);
mld_shake128_finalize(&shake128_once);
mld_shake128_squeeze(once, sizeof(once), &shake128_once);
mld_shake128_release(&shake128_once);

mld_shake128_init(&shake128_twice);
mld_shake128_absorb(&shake128_twice, input, input_lengths[round]);
mld_shake128_finalize(&shake128_twice);
mld_shake128_finalize(&shake128_twice);
mld_shake128_squeeze(twice, sizeof(twice), &shake128_twice);
mld_shake128_release(&shake128_twice);
CHECK(memcmp(once, twice, sizeof(once)) == 0);

memset(once, 0, sizeof(once));
memset(twice, 0, sizeof(twice));
mld_shake256_init(&shake256_once);
mld_shake256_absorb(&shake256_once, input, input_lengths[round]);
mld_shake256_finalize(&shake256_once);
mld_shake256_squeeze(once, sizeof(once), &shake256_once);
mld_shake256_release(&shake256_once);

mld_shake256_init(&shake256_twice);
mld_shake256_absorb(&shake256_twice, input, input_lengths[round]);
mld_shake256_finalize(&shake256_twice);
mld_shake256_finalize(&shake256_twice);
mld_shake256_squeeze(twice, sizeof(twice), &shake256_twice);
mld_shake256_release(&shake256_twice);
CHECK(memcmp(once, twice, sizeof(once)) == 0);
}

return 0;
}

#if defined(MLD_USE_NATIVE_FIPS202_X1)
static void print_u64_array(const char *label, const uint64_t *array,
size_t len)
Expand Down Expand Up @@ -1412,6 +1482,8 @@ int main(void)
* Normally, you would want to seed a PRNG with trustworthy entropy here. */
randombytes_reset();

CHECK(test_shake_finalize_idempotent() == 0);

#if !defined(MLD_CONFIG_NO_SIGN_API)
CHECK(test_polyvec_lazy_eager() == 0);
#endif
Expand Down
Loading