Skip to content

Commit

Permalink
add keccakx interface
Browse files Browse the repository at this point in the history
Signed-off-by: Duc Tri Nguyen <[email protected]>

rename to x4

add shake256x4 interface

add shake256x4

add batch getnoise sampling
  • Loading branch information
cothan committed Jun 19, 2024
1 parent 4c2e281 commit d703199
Show file tree
Hide file tree
Showing 6 changed files with 531 additions and 41 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ NISTFLAGS += -Wno-unused-result -O3 -fomit-frame-pointer
RM = /bin/rm

SOURCES = mlkem/kem.c mlkem/indcpa.c mlkem/polyvec.c mlkem/poly.c mlkem/ntt.c mlkem/cbd.c mlkem/reduce.c mlkem/verify.c
SOURCESKECCAK = $(SOURCES) fips202/keccakf1600.c fips202/fips202.c mlkem/symmetric-shake.c
SOURCESKECCAK = $(SOURCES) fips202/keccakf1600.c fips202/fips202.c fips202/fips202x4.c mlkem/symmetric-shake.c
SOURCESKECCAKRANDOM = $(SOURCESKECCAK) randombytes/randombytes.c
SOURCESNISTKATS = $(SOURCESKECCAK) test/nistrng/aes.c test/nistrng/rng.c

HEADERS = mlkem/params.h mlkem/kem.h mlkem/indcpa.h mlkem/polyvec.h mlkem/poly.h mlkem/ntt.h mlkem/cbd.h mlkem/reduce.h mlkem/verify.h mlkem/symmetric.h
HEADERSKECCAK = $(HEADERS) fips202/keccakf1600.h fips202/fips202.h
HEADERS = mlkem/params.h mlkem/kem.h mlkem/indcpa.h mlkem/polyvec.h mlkem/poly.h mlkem/ntt.h mlkem/cbd.h mlkem/reduce.c mlkem/verify.h mlkem/symmetric.h
HEADERSKECCAK = $(HEADERS) fips202/keccakf1600.h fips202/fips202.h fips202/fips202x4.h
HEADERSKECCAKRANDOM = $(HEADERSKECCAK) randombytes/randombytes.h
HEADERNISTKATS = $(HEADERSKECCAK) test/nistrng/aes.h test/nistrng/randombytes.h

Expand Down
242 changes: 242 additions & 0 deletions fips202/fips202x4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
// SPDX-License-Identifier: Apache-2.0
#include <string.h>
#include "fips202x4.h"
#include "fips202.h"
#include "keccakf1600.h"

#define KECCAK_CTX 25

static void keccak_absorb_x4(uint64_t *s, uint32_t r,
const uint8_t *in0,
const uint8_t *in1,
const uint8_t *in2,
const uint8_t *in3,
size_t inlen,
uint8_t p)
{

while (inlen >= r)
{

KeccakF1600_StateXORBytes(s + KECCAK_CTX * 0, in0, 0, r);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 1, in1, 0, r);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 2, in2, 0, r);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 3, in3, 0, r);

KeccakF1600_StatePermute(s + KECCAK_CTX * 0);
KeccakF1600_StatePermute(s + KECCAK_CTX * 1);
KeccakF1600_StatePermute(s + KECCAK_CTX * 2);
KeccakF1600_StatePermute(s + KECCAK_CTX * 3);

in0 += r;
in1 += r;
in2 += r;
in3 += r;
inlen -= r;
}

if (inlen > 0)
{
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 0, in0, 0, inlen);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 1, in1, 0, inlen);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 2, in2, 0, inlen);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 3, in3, 0, inlen);
}

if (inlen == r - 1)
{
p |= 128;
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 0, &p, inlen, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 1, &p, inlen, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 2, &p, inlen, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 3, &p, inlen, 1);
}
else
{
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 0, &p, inlen, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 1, &p, inlen, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 2, &p, inlen, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 3, &p, inlen, 1);
p = 128;
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 0, &p, r - 1, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 1, &p, r - 1, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 2, &p, r - 1, 1);
KeccakF1600_StateXORBytes(s + KECCAK_CTX * 3, &p, r - 1, 1);
}
}

static void keccak_squeezeblocks_x4(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t nblocks,
uint64_t *s,
uint32_t r)
{

while (nblocks > 0)
{
KeccakF1600_StatePermute(s + KECCAK_CTX * 0);
KeccakF1600_StatePermute(s + KECCAK_CTX * 1);
KeccakF1600_StatePermute(s + KECCAK_CTX * 2);
KeccakF1600_StatePermute(s + KECCAK_CTX * 3);

KeccakF1600_StateExtractBytes(s + KECCAK_CTX * 0, out0, 0, r);
KeccakF1600_StateExtractBytes(s + KECCAK_CTX * 1, out1, 0, r);
KeccakF1600_StateExtractBytes(s + KECCAK_CTX * 2, out2, 0, r);
KeccakF1600_StateExtractBytes(s + KECCAK_CTX * 3, out3, 0, r);

out0 += r;
out1 += r;
out2 += r;
out3 += r;
nblocks--;
}
}

uint64_t *keccakx_get_lane_state(keccakx4_state *state, size_t index)
{
if (index >= KECCAK_WAY)
{
return NULL;
}

return state->ctx + index *KECCAK_CTX;
}

int shake128x4_absorb(keccakx4_state *state,
const uint8_t *in0,
const uint8_t *in1,
const uint8_t *in2,
const uint8_t *in3,
size_t inlen)
{
if (state == NULL || in0 == NULL || in1 == NULL || in2 == NULL || in3 == NULL)
{
return 1;
}

memset(state->ctx, 0, sizeof(state->ctx));

keccak_absorb_x4(state->ctx, SHAKE128_RATE, in0, in1, in2, in3, inlen, 0x1F);

return 0;
}

int shake256x4_absorb(keccakx4_state *state,
const uint8_t *in0,
const uint8_t *in1,
const uint8_t *in2,
const uint8_t *in3,
size_t inlen)
{
if (state == NULL || in0 == NULL || in1 == NULL || in2 == NULL || in3 == NULL)
{
return 1;
}

memset(state->ctx, 0, sizeof(state->ctx));

keccak_absorb_x4(state->ctx, SHAKE256_RATE, in0, in1, in2, in3, inlen, 0x1F);

return 0;
}


int shake128x4_squeezeblocks(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t nblocks,
keccakx4_state *state)
{
if (state == NULL || out0 == NULL || out1 == NULL || out2 == NULL || out3 == NULL)
{
return 1;
}
keccak_squeezeblocks_x4(out0, out1, out2, out3, nblocks, state->ctx, SHAKE128_RATE);

return 0;
}

int shake256x4_squeezeblocks(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t nblocks,
keccakx4_state *state)
{

if (state == NULL || out0 == NULL || out1 == NULL || out2 == NULL || out3 == NULL)
{
return 1;
}
keccak_squeezeblocks_x4(out0, out1, out2, out3, nblocks, state->ctx, SHAKE256_RATE);

return 0;
}

int shake256x1_squeezeblocks(uint8_t *out,
size_t nblocks,
size_t index,
keccakx4_state *state)
{
if (out == NULL)
{
return 1;
}
uint64_t *ctx = keccakx_get_lane_state(state, index);
while (nblocks > 0)
{
KeccakF1600_StatePermute(ctx);
KeccakF1600_StateExtractBytes(ctx, out, 0, SHAKE128_RATE);
out += SHAKE128_RATE;
nblocks--;
}

return 0;
}

int shake256x4(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t outlen,
uint8_t *in0,
uint8_t *in1,
uint8_t *in2,
uint8_t *in3,
size_t inlen)
{
if (in0 == NULL || in1 == NULL || in2 == NULL || in3 == NULL ||
out0 == NULL || out1 == NULL || out2 == NULL || out3 == NULL)
{
return 1;
}

keccakx4_state statex;
size_t nblocks = outlen/SHAKE256_RATE;
uint8_t tmp[KECCAK_WAY][SHAKE256_RATE];

shake256x4_absorb(&statex, in0, in1, in2, in3, inlen);

shake256x4_squeezeblocks(out0, out1, out2, out3, nblocks, &statex);

out0 += nblocks * SHAKE256_RATE;
out1 += nblocks * SHAKE256_RATE;
out2 += nblocks * SHAKE256_RATE;
out3 += nblocks * SHAKE256_RATE;

outlen -= nblocks * SHAKE256_RATE;

if (outlen)
{
shake256x4_squeezeblocks(tmp[0], tmp[1], tmp[2], tmp[3], 1, &statex);
memcpy(out0, tmp[0], outlen);
memcpy(out1, tmp[1], outlen);
memcpy(out2, tmp[2], outlen);
memcpy(out3, tmp[3], outlen);
}

return 0;
}
66 changes: 66 additions & 0 deletions fips202/fips202x4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: Apache-2.0
#ifndef FIPS_202X_H
#define FIPS_202X_H

#ifndef KECCAK_WAY
#define KECCAK_WAY 4
#endif

#include <stdint.h>

typedef struct
{
uint64_t ctx[25 * KECCAK_WAY];
} keccakx4_state;

uint64_t *keccakx_get_lane_state(keccakx4_state *state, size_t index);

int shake128x4_absorb(keccakx4_state *state,
const uint8_t *in0,
const uint8_t *in1,
const uint8_t *in2,
const uint8_t *in3,
size_t inlen);

int shake256x4_absorb(keccakx4_state *state,
const uint8_t *in0,
const uint8_t *in1,
const uint8_t *in2,
const uint8_t *in3,
size_t inlen);


int shake128x4_squeezeblocks(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t nblocks,
keccakx4_state *state);

int shake256x4_squeezeblocks(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t nblocks,
keccakx4_state *state);

/*
* Squeezes a single lane in Keccak 4-way
*/
int shake256x1_squeezeblocks(uint8_t *out,
size_t nblocks,
size_t index,
keccakx4_state *state);

int shake256x4(uint8_t *out0,
uint8_t *out1,
uint8_t *out2,
uint8_t *out3,
size_t outlen,
uint8_t *in0,
uint8_t *in1,
uint8_t *in2,
uint8_t *in3,
size_t inlen);

#endif
Loading

0 comments on commit d703199

Please sign in to comment.