mlkem_test: add mlkem-native

This commit is contained in:
2026-07-05 21:26:19 +08:00
parent b8ddb2ef08
commit cd039e2e2e
126 changed files with 37929 additions and 0 deletions

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [FIPS203]
* FIPS 203 Module-Lattice-Based Key-Encapsulation Mechanism Standard
* National Institute of Standards and Technology
* https://csrc.nist.gov/pubs/fips/203/final
*
* - [mupq]
* Common files for pqm4, pqm3, pqriscv
* Kannwischer, Petri, Rijneveld, Schwabe, Stoffelen
* https://github.com/mupq/mupq
*
* - [supercop]
* SUPERCOP benchmarking framework
* Daniel J. Bernstein
* http://bench.cr.yp.to/supercop.html
*
* - [tweetfips]
* 'tweetfips202' FIPS202 implementation
* Van Assche, Bernstein, Schwabe
* https://keccak.team/2015/tweetfips202.html
*/
/* Based on the CC0 implementation from @[mupq] and the public domain
* implementation @[supercop, crypto_hash/keccakc512/simple/]
* by Ronny Van Keer, and the public domain @[tweetfips] implementation. */
#include "../common.h"
#if !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#include "../verify.h"
#include "fips202.h"
#include "keccakf1600.h"
/**
* Absorb step of Keccak; non-incremental, starts by zeroeing the state.
*
* @warning Must only be called once.
*
* @param[out] s Pointer to (uninitialized) output Keccak state.
* @param r Rate in bytes (e.g., 168 for SHAKE128).
* @param[in] m Input to be absorbed into @p s.
* @param mlen Length of input in bytes.
* @param p Domain-separation byte for different Keccak-derived
* functions.
*/
static void mlk_keccak_absorb_once(uint64_t *s, unsigned r, const uint8_t *m,
size_t mlen, uint8_t p)
__contract__(
requires(mlen <= MLK_MAX_BUFFER_SIZE)
requires(r > 0)
requires(r <= sizeof(uint64_t) * MLK_KECCAK_LANES)
requires(memory_no_alias(s, sizeof(uint64_t) * MLK_KECCAK_LANES))
requires(memory_no_alias(m, mlen))
assigns(memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES)))
{
/* Initialize state */
size_t i;
for (i = 0; i < 25; ++i)
__loop__(invariant(i <= 25)
decreases(25 - i))
{
s[i] = 0;
}
while (mlen >= r)
__loop__(
assigns(mlen, m, memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES))
invariant(mlen <= loop_entry(mlen))
invariant(m == loop_entry(m) + (loop_entry(mlen) - mlen))
decreases(mlen))
{
mlk_keccakf1600_xor_bytes(s, m, 0, r);
mlk_keccakf1600_permute(s);
mlen -= r;
m += r;
}
/* At this point, mlen < r, so the truncations to unsigned are safe below. */
if (mlen > 0)
{
mlk_keccakf1600_xor_bytes(s, m, 0, (unsigned int)mlen);
}
if (mlen == r - 1)
{
p |= 128;
mlk_keccakf1600_xor_bytes(s, &p, (unsigned int)mlen, 1);
}
else
{
mlk_keccakf1600_xor_bytes(s, &p, (unsigned int)mlen, 1);
p = 128;
mlk_keccakf1600_xor_bytes(s, &p, r - 1, 1);
}
}
/**
* Block-level Keccak squeeze.
*
* @param[out] h Output bytes.
* @param nblocks Number of blocks to be squeezed.
* @param[in,out] s Input/output state.
* @param r Rate in bytes (e.g., 168 for SHAKE128).
*/
static void mlk_keccak_squeezeblocks(uint8_t *h, size_t nblocks, uint64_t *s,
unsigned r)
__contract__(
requires(r <= sizeof(uint64_t) * MLK_KECCAK_LANES)
requires(nblocks <= 8 /* somewhat arbitrary bound */)
requires(memory_no_alias(s, sizeof(uint64_t) * MLK_KECCAK_LANES))
requires(memory_no_alias(h, nblocks * r))
assigns(memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES))
assigns(memory_slice(h, nblocks * r)))
{
while (nblocks > 0)
__loop__(
assigns(h, nblocks,
memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES),
memory_slice(h, nblocks * r))
invariant(nblocks <= loop_entry(nblocks) &&
h == loop_entry(h) + r * (loop_entry(nblocks) - nblocks))
decreases(nblocks))
{
mlk_keccakf1600_permute(s);
mlk_keccakf1600_extract_bytes(s, h, 0, r);
h += r;
nblocks--;
}
}
/**
* Keccak squeeze; can be called on byte-level.
*
* @warning Must only be called once.
*
* @param[out] h Output bytes.
* @param outlen Number of bytes to be squeezed.
* @param[in,out] s Keccak state.
* @param r Rate in bytes (e.g., 168 for SHAKE128).
*/
static void mlk_keccak_squeeze_once(uint8_t *h, size_t outlen, uint64_t *s,
unsigned r)
__contract__(
requires(outlen <= MLK_MAX_BUFFER_SIZE)
requires(r > 0)
requires(r <= sizeof(uint64_t) * MLK_KECCAK_LANES)
requires(memory_no_alias(s, sizeof(uint64_t) * MLK_KECCAK_LANES))
requires(memory_no_alias(h, outlen))
assigns(memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES))
assigns(memory_slice(h, outlen)))
{
size_t len;
while (outlen > 0)
__loop__(
assigns(len, h, outlen,
memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES),
memory_slice(h, outlen))
invariant(outlen <= loop_entry(outlen) &&
h == loop_entry(h) + (loop_entry(outlen) - outlen))
decreases(outlen))
{
mlk_keccakf1600_permute(s);
if (outlen < r)
{
len = outlen;
}
else
{
len = r;
}
mlk_keccakf1600_extract_bytes(s, h, 0, (unsigned int)len);
h += len;
outlen -= len;
}
}
void mlk_shake128_absorb_once(mlk_shake128ctx *state, const uint8_t *input,
size_t inlen)
{
mlk_keccak_absorb_once(state->ctx, SHAKE128_RATE, input, inlen, 0x1F);
}
void mlk_shake128_squeezeblocks(uint8_t *output, size_t nblocks,
mlk_shake128ctx *state)
{
mlk_keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE128_RATE);
}
void mlk_shake128_init(mlk_shake128ctx *state) { (void)state; }
void mlk_shake128_release(mlk_shake128ctx *state)
{
/* Specification: Partially implements
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
mlk_zeroize(state, sizeof(mlk_shake128ctx));
}
typedef mlk_shake128ctx mlk_shake256ctx;
void mlk_shake256(uint8_t *output, size_t outlen, const uint8_t *input,
size_t inlen)
{
mlk_shake256ctx state;
/* Absorb input */
mlk_keccak_absorb_once(state.ctx, SHAKE256_RATE, input, inlen, 0x1F);
/* Squeeze output */
mlk_keccak_squeeze_once(output, outlen, state.ctx, SHAKE256_RATE);
/* Specification: Partially implements
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
mlk_zeroize(&state, sizeof(state));
}
void mlk_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen)
{
uint64_t ctx[25];
/* Absorb input */
mlk_keccak_absorb_once(ctx, SHA3_256_RATE, input, inlen, 0x06);
/* Squeeze output */
mlk_keccak_squeeze_once(output, 32, ctx, SHA3_256_RATE);
/* Specification: Partially implements
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
mlk_zeroize(ctx, sizeof(ctx));
}
void mlk_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen)
{
uint64_t ctx[25];
/* Absorb input */
mlk_keccak_absorb_once(ctx, SHA3_512_RATE, input, inlen, 0x06);
/* Squeeze output */
mlk_keccak_squeeze_once(output, 64, ctx, SHA3_512_RATE);
/* Specification: Partially implements
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
mlk_zeroize(ctx, sizeof(ctx));
}
#else /* !MLK_CONFIG_MULTILEVEL_NO_SHARED */
MLK_EMPTY_CU(fips202)
#endif /* MLK_CONFIG_MULTILEVEL_NO_SHARED */

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_FIPS202_H
#define MLK_FIPS202_FIPS202_H
#include "../cbmc.h"
#include "../common.h"
#define SHAKE128_RATE 168
#define SHAKE256_RATE 136
#define SHA3_256_RATE 136
#define SHA3_384_RATE 104
#define SHA3_512_RATE 72
/** Context for the non-incremental SHAKE128 API. */
typedef struct
{
uint64_t ctx[25]; /**< Keccak state. */
} MLK_ALIGN mlk_shake128ctx;
#define mlk_shake128_absorb_once MLK_NAMESPACE(shake128_absorb_once)
/**
* One-shot absorb step of the SHAKE128 XOF.
*
* For call-sites (in mlkem-native):
* - This function MUST ONLY be called straight after mlk_shake128_init().
* - This function MUST ONLY be called once.
*
* Consequently, for providers of custom FIPS202 code to be used with
* mlkem-native:
* - You may assume that the input context is freshly initialized via
* mlk_shake128_init().
* - You may assume that this function is called exactly once.
*
* @param[in,out] state SHAKE128 context.
* @param[in] input Input to be absorbed into the state.
* @param inlen Length of input in bytes.
*/
void mlk_shake128_absorb_once(mlk_shake128ctx *state, const uint8_t *input,
size_t inlen)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(state, sizeof(mlk_shake128ctx)))
requires(memory_no_alias(input, inlen))
assigns(memory_slice(state, sizeof(mlk_shake128ctx)))
);
#define mlk_shake128_squeezeblocks MLK_NAMESPACE(shake128_squeezeblocks)
/**
* Squeeze step of SHAKE128 XOF. Squeezes full blocks of SHAKE128_RATE bytes
* each. Modifies the state. Can be called multiple times to keep squeezing,
* i.e., is incremental.
*
* @param[out] output Output blocks.
* @param nblocks Number of blocks to be squeezed (written to output).
* @param[in,out] state Keccak state.
*/
void mlk_shake128_squeezeblocks(uint8_t *output, size_t nblocks,
mlk_shake128ctx *state)
__contract__(
requires(nblocks <= 8 /* somewhat arbitrary bound */)
requires(memory_no_alias(state, sizeof(mlk_shake128ctx)))
requires(memory_no_alias(output, nblocks * SHAKE128_RATE))
assigns(memory_slice(output, nblocks * SHAKE128_RATE), memory_slice(state, sizeof(mlk_shake128ctx)))
);
#define mlk_shake128_init MLK_NAMESPACE(shake128_init)
void mlk_shake128_init(mlk_shake128ctx *state);
#define mlk_shake128_release MLK_NAMESPACE(shake128_release)
void mlk_shake128_release(mlk_shake128ctx *state);
/* One-stop SHAKE256 call. Aliasing between input and
* output is not permitted */
#define mlk_shake256 MLK_NAMESPACE(shake256)
/**
* SHAKE256 XOF with non-incremental API.
*
* @param[out] output Output buffer.
* @param outlen Requested output length in bytes.
* @param[in] input Input buffer.
* @param inlen Length of input in bytes.
*/
void mlk_shake256(uint8_t *output, size_t outlen, const uint8_t *input,
size_t inlen)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(outlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(input, inlen))
requires(memory_no_alias(output, outlen))
assigns(memory_slice(output, outlen))
);
/* One-stop SHA3_256 call. Aliasing between input and
* output is not permitted */
#define SHA3_256_HASHBYTES 32
#define mlk_sha3_256 MLK_NAMESPACE(sha3_256)
/**
* SHA3-256 with non-incremental API.
*
* @param[out] output Output buffer.
* @param[in] input Input buffer.
* @param inlen Length of input in bytes.
*/
void mlk_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(input, inlen))
requires(memory_no_alias(output, SHA3_256_HASHBYTES))
assigns(memory_slice(output, SHA3_256_HASHBYTES))
);
/* One-stop SHA3_512 call. Aliasing between input and
* output is not permitted */
#define SHA3_512_HASHBYTES 64
#define mlk_sha3_512 MLK_NAMESPACE(sha3_512)
/**
* SHA3-512 with non-incremental API.
*
* @param[out] output Output buffer.
* @param[in] input Input buffer.
* @param inlen Length of input in bytes.
*/
void mlk_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(input, inlen))
requires(memory_no_alias(output, SHA3_512_HASHBYTES))
assigns(memory_slice(output, SHA3_512_HASHBYTES))
);
#if !defined(MLK_CONFIG_USE_NATIVE_BACKEND_FIPS202) || \
!defined(MLK_USE_FIPS202_X4_NATIVE)
/* If you provide your own FIPS-202 implementation where the x4-
* Keccak-f1600-x4 implementation falls back to 4-fold Keccak-f1600,
* set this to gain a small speedup. */
#define FIPS202_X4_DEFAULT_IMPLEMENTATION
#endif /* !MLK_CONFIG_USE_NATIVE_BACKEND_FIPS202 || !MLK_USE_FIPS202_X4_NATIVE \
*/
#endif /* !MLK_FIPS202_FIPS202_H */

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [FIPS203]
* FIPS 203 Module-Lattice-Based Key-Encapsulation Mechanism Standard
* National Institute of Standards and Technology
* https://csrc.nist.gov/pubs/fips/203/final
*/
#include "../common.h"
#if !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#include "../verify.h"
#include "fips202.h"
#include "fips202x4.h"
#include "keccakf1600.h"
typedef mlk_shake128x4ctx mlk_shake256x4_ctx;
static void mlk_keccak_absorb_once_x4(uint64_t *s, unsigned r,
const uint8_t *in0, const uint8_t *in1,
const uint8_t *in2, const uint8_t *in3,
size_t inlen, uint8_t p)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(s, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
requires(r > 0)
requires(r <= sizeof(uint64_t) * MLK_KECCAK_LANES)
requires(memory_no_alias(in0, inlen))
requires(memory_no_alias(in1, inlen))
requires(memory_no_alias(in2, inlen))
requires(memory_no_alias(in3, inlen))
assigns(memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY)))
{
while (inlen >= r)
__loop__(
assigns(inlen, in0, in1, in2, in3, memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
invariant(inlen <= loop_entry(inlen))
invariant(in0 == loop_entry(in0) + (loop_entry(inlen) - inlen))
invariant(in1 == loop_entry(in1) + (loop_entry(inlen) - inlen))
invariant(in2 == loop_entry(in2) + (loop_entry(inlen) - inlen))
invariant(in3 == loop_entry(in3) + (loop_entry(inlen) - inlen))
decreases(inlen))
{
mlk_keccakf1600x4_xor_bytes(s, in0, in1, in2, in3, 0, r);
mlk_keccakf1600x4_permute(s);
in0 += r;
in1 += r;
in2 += r;
in3 += r;
inlen -= r;
}
/* At this point, inlen < r, so the truncations to unsigned are safe below. */
if (inlen > 0)
{
mlk_keccakf1600x4_xor_bytes(s, in0, in1, in2, in3, 0, (unsigned int)inlen);
}
if (inlen == r - 1)
{
p |= 128;
mlk_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, (unsigned int)inlen, 1);
}
else
{
mlk_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, (unsigned int)inlen, 1);
p = 128;
mlk_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, r - 1, 1);
}
}
static void mlk_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 <= sizeof(uint64_t) * MLK_KECCAK_LANES)
requires(r == SHAKE128_RATE || r == SHAKE256_RATE)
requires(nblocks <= (MLK_MAX_BUFFER_SIZE / SHAKE256_RATE))
requires(memory_no_alias(s, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
requires(memory_no_alias(out0, nblocks * r))
requires(memory_no_alias(out1, nblocks * r))
requires(memory_no_alias(out2, nblocks * r))
requires(memory_no_alias(out3, nblocks * r))
assigns(memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
assigns(memory_slice(out0, nblocks * r))
assigns(memory_slice(out1, nblocks * r))
assigns(memory_slice(out2, nblocks * r))
assigns(memory_slice(out3, nblocks * r)))
{
size_t current_offset = 0;
while (nblocks > 0)
__loop__(
assigns(nblocks, current_offset,
memory_slice(s, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY),
memory_slice(out0, nblocks * r),
memory_slice(out1, nblocks * r),
memory_slice(out2, nblocks * r),
memory_slice(out3, nblocks * r))
invariant(nblocks <= loop_entry(nblocks))
invariant(current_offset == (loop_entry(nblocks) - nblocks) * r)
decreases(nblocks))
{
mlk_keccakf1600x4_permute(s);
mlk_keccakf1600x4_extract_bytes(
s, &out0[current_offset], &out1[current_offset], &out2[current_offset],
&out3[current_offset], 0, r);
current_offset += r;
nblocks--;
}
}
void mlk_shake128x4_absorb_once(mlk_shake128x4ctx *state, const uint8_t *in0,
const uint8_t *in1, const uint8_t *in2,
const uint8_t *in3, size_t inlen)
{
mlk_memset(state, 0, sizeof(mlk_shake128x4ctx));
mlk_keccak_absorb_once_x4(state->ctx, SHAKE128_RATE, in0, in1, in2, in3,
inlen, 0x1F);
}
void mlk_shake128x4_squeezeblocks(uint8_t *out0, uint8_t *out1, uint8_t *out2,
uint8_t *out3, size_t nblocks,
mlk_shake128x4ctx *state)
{
mlk_keccak_squeezeblocks_x4(out0, out1, out2, out3, nblocks, state->ctx,
SHAKE128_RATE);
}
void mlk_shake128x4_init(mlk_shake128x4ctx *state) { (void)state; }
void mlk_shake128x4_release(mlk_shake128x4ctx *state)
{
/* Specification: Partially implements
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
mlk_zeroize(state, sizeof(mlk_shake128x4ctx));
}
static void mlk_shake256x4_absorb_once(mlk_shake256x4_ctx *state,
const uint8_t *in0, const uint8_t *in1,
const uint8_t *in2, const uint8_t *in3,
size_t inlen)
{
mlk_memset(state, 0, sizeof(mlk_shake128x4ctx));
mlk_keccak_absorb_once_x4(state->ctx, SHAKE256_RATE, in0, in1, in2, in3,
inlen, 0x1F);
}
static void mlk_shake256x4_squeezeblocks(uint8_t *out0, uint8_t *out1,
uint8_t *out2, uint8_t *out3,
size_t nblocks,
mlk_shake256x4_ctx *state)
{
mlk_keccak_squeezeblocks_x4(out0, out1, out2, out3, nblocks, state->ctx,
SHAKE256_RATE);
}
void mlk_shake256x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3,
size_t outlen, const uint8_t *in0, const uint8_t *in1,
const uint8_t *in2, const uint8_t *in3, size_t inlen)
{
mlk_shake256x4_ctx statex;
size_t nblocks = outlen / SHAKE256_RATE;
uint8_t tmp0[SHAKE256_RATE];
uint8_t tmp1[SHAKE256_RATE];
uint8_t tmp2[SHAKE256_RATE];
uint8_t tmp3[SHAKE256_RATE];
mlk_shake256x4_absorb_once(&statex, in0, in1, in2, in3, inlen);
mlk_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)
{
mlk_shake256x4_squeezeblocks(tmp0, tmp1, tmp2, tmp3, 1, &statex);
mlk_memcpy(out0, tmp0, outlen);
mlk_memcpy(out1, tmp1, outlen);
mlk_memcpy(out2, tmp2, outlen);
mlk_memcpy(out3, tmp3, outlen);
}
/* Specification: Partially implements
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
mlk_zeroize(&statex, sizeof(statex));
mlk_zeroize(tmp0, sizeof(tmp0));
mlk_zeroize(tmp1, sizeof(tmp1));
mlk_zeroize(tmp2, sizeof(tmp2));
mlk_zeroize(tmp3, sizeof(tmp3));
}
#else /* !MLK_CONFIG_MULTILEVEL_NO_SHARED */
MLK_EMPTY_CU(fips202x4)
#endif /* MLK_CONFIG_MULTILEVEL_NO_SHARED */

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_FIPS202X4_H
#define MLK_FIPS202_FIPS202X4_H
#include "../cbmc.h"
#include "../common.h"
#include "fips202.h"
#include "keccakf1600.h"
/** Context for the non-incremental 4-way SHAKE128 API. */
typedef struct
{
uint64_t ctx[MLK_KECCAK_LANES *
MLK_KECCAK_WAY]; /**< 4-way Keccak state, stored sequentially. */
} MLK_ALIGN mlk_shake128x4ctx;
#define mlk_shake128x4_absorb_once MLK_NAMESPACE(shake128x4_absorb_once)
void mlk_shake128x4_absorb_once(mlk_shake128x4ctx *state, const uint8_t *in0,
const uint8_t *in1, const uint8_t *in2,
const uint8_t *in3, size_t inlen)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(state, sizeof(mlk_shake128x4ctx)))
requires(memory_no_alias(in0, inlen))
requires(memory_no_alias(in1, inlen))
requires(memory_no_alias(in2, inlen))
requires(memory_no_alias(in3, inlen))
assigns(memory_slice(state, sizeof(mlk_shake128x4ctx)))
);
#define mlk_shake128x4_squeezeblocks MLK_NAMESPACE(shake128x4_squeezeblocks)
void mlk_shake128x4_squeezeblocks(uint8_t *out0, uint8_t *out1, uint8_t *out2,
uint8_t *out3, size_t nblocks,
mlk_shake128x4ctx *state)
__contract__(
requires(nblocks <= 8 /* somewhat arbitrary bound */)
requires(memory_no_alias(state, sizeof(mlk_shake128x4ctx)))
requires(memory_no_alias(out0, nblocks * SHAKE128_RATE))
requires(memory_no_alias(out1, nblocks * SHAKE128_RATE))
requires(memory_no_alias(out2, nblocks * SHAKE128_RATE))
requires(memory_no_alias(out3, nblocks * SHAKE128_RATE))
assigns(memory_slice(out0, nblocks * SHAKE128_RATE),
memory_slice(out1, nblocks * SHAKE128_RATE),
memory_slice(out2, nblocks * SHAKE128_RATE),
memory_slice(out3, nblocks * SHAKE128_RATE),
memory_slice(state, sizeof(mlk_shake128x4ctx)))
);
#define mlk_shake128x4_init MLK_NAMESPACE(shake128x4_init)
void mlk_shake128x4_init(mlk_shake128x4ctx *state);
#define mlk_shake128x4_release MLK_NAMESPACE(shake128x4_release)
void mlk_shake128x4_release(mlk_shake128x4ctx *state);
#define mlk_shake256x4 MLK_NAMESPACE(shake256x4)
void mlk_shake256x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_t *out3,
size_t outlen, const uint8_t *in0, const uint8_t *in1,
const uint8_t *in2, const uint8_t *in3, size_t inlen)
__contract__(
requires(inlen <= MLK_MAX_BUFFER_SIZE)
requires(outlen <= MLK_MAX_BUFFER_SIZE)
requires(memory_no_alias(in0, inlen))
requires(memory_no_alias(in1, inlen))
requires(memory_no_alias(in2, inlen))
requires(memory_no_alias(in3, inlen))
requires(memory_no_alias(out0, outlen))
requires(memory_no_alias(out1, outlen))
requires(memory_no_alias(out2, outlen))
requires(memory_no_alias(out3, outlen))
assigns(memory_slice(out0, outlen))
assigns(memory_slice(out1, outlen))
assigns(memory_slice(out2, outlen))
assigns(memory_slice(out3, outlen))
);
#endif /* !MLK_FIPS202_FIPS202X4_H */

View File

@@ -0,0 +1,499 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [mupq]
* Common files for pqm4, pqm3, pqriscv
* Kannwischer, Petri, Rijneveld, Schwabe, Stoffelen
* https://github.com/mupq/mupq
*
* - [supercop]
* SUPERCOP benchmarking framework
* Daniel J. Bernstein
* http://bench.cr.yp.to/supercop.html
*
* - [tweetfips]
* 'tweetfips202' FIPS202 implementation
* Van Assche, Bernstein, Schwabe
* https://keccak.team/2015/tweetfips202.html
*/
/* Based on the CC0 implementation from @[mupq] and the public domain
* implementation @[supercop, crypto_hash/keccakc512/simple/]
* by Ronny Van Keer, and the public domain @[tweetfips] implementation. */
#include "keccakf1600.h"
#if !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#define MLK_KECCAK_NROUNDS 24
#define MLK_KECCAK_ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
void mlk_keccakf1600_extract_bytes(uint64_t *state, unsigned char *data,
unsigned offset, unsigned length)
{
unsigned i;
#if defined(MLK_SYS_LITTLE_ENDIAN)
uint8_t *state_ptr = (uint8_t *)state + offset;
for (i = 0; i < length; i++)
__loop__(invariant(i <= length)
decreases(length - i))
{
data[i] = state_ptr[i];
}
#else /* MLK_SYS_LITTLE_ENDIAN */
/* Portable version */
for (i = 0; i < length; i++)
__loop__(invariant(i <= length)
decreases(length - i))
{
data[i] = (state[(offset + i) >> 3] >> (8 * ((offset + i) & 0x07))) & 0xFF;
}
#endif /* !MLK_SYS_LITTLE_ENDIAN */
}
void mlk_keccakf1600_xor_bytes(uint64_t *state, const unsigned char *data,
unsigned offset, unsigned length)
{
unsigned i;
#if defined(MLK_SYS_LITTLE_ENDIAN)
uint8_t *state_ptr = (uint8_t *)state + offset;
for (i = 0; i < length; i++)
__loop__(invariant(i <= length)
decreases(length - i))
{
state_ptr[i] ^= data[i];
}
#else /* MLK_SYS_LITTLE_ENDIAN */
/* Portable version */
for (i = 0; i < length; i++)
__loop__(invariant(i <= length)
decreases(length - i))
{
state[(offset + i) >> 3] ^= (uint64_t)data[i]
<< (8 * ((offset + i) & 0x07));
}
#endif /* !MLK_SYS_LITTLE_ENDIAN */
}
static void mlk_keccakf1600x4_extract_bytes_c(uint64_t *state,
unsigned char *data0,
unsigned char *data1,
unsigned char *data2,
unsigned char *data3,
unsigned offset, unsigned length)
__contract__(
requires(0 <= offset && offset <= MLK_KECCAK_LANES * sizeof(uint64_t) &&
0 <= length && length <= MLK_KECCAK_LANES * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
requires(memory_no_alias(data0, length))
requires(memory_no_alias(data1, length))
requires(memory_no_alias(data2, length))
requires(memory_no_alias(data3, length))
assigns(memory_slice(data0, length))
assigns(memory_slice(data1, length))
assigns(memory_slice(data2, length))
assigns(memory_slice(data3, length))
)
{
mlk_keccakf1600_extract_bytes(state + MLK_KECCAK_LANES * 0, data0, offset,
length);
mlk_keccakf1600_extract_bytes(state + MLK_KECCAK_LANES * 1, data1, offset,
length);
mlk_keccakf1600_extract_bytes(state + MLK_KECCAK_LANES * 2, data2, offset,
length);
mlk_keccakf1600_extract_bytes(state + MLK_KECCAK_LANES * 3, data3, offset,
length);
}
void mlk_keccakf1600x4_extract_bytes(uint64_t *state, unsigned char *data0,
unsigned char *data1, unsigned char *data2,
unsigned char *data3, unsigned offset,
unsigned length)
{
#if defined(MLK_USE_FIPS202_X4_EXTRACT_BYTES_NATIVE)
if (mlk_keccakf1600_extract_bytes_x4_native(state, data0, data1, data2, data3,
offset, length) ==
MLK_NATIVE_FUNC_SUCCESS)
{
return;
}
#endif /* MLK_USE_FIPS202_X4_EXTRACT_BYTES_NATIVE */
mlk_keccakf1600x4_extract_bytes_c(state, data0, data1, data2, data3, offset,
length);
}
static void mlk_keccakf1600x4_xor_bytes_c(uint64_t *state,
const unsigned char *data0,
const unsigned char *data1,
const unsigned char *data2,
const unsigned char *data3,
unsigned offset, unsigned length)
__contract__(
requires(0 <= offset && offset <= MLK_KECCAK_LANES * sizeof(uint64_t) &&
0 <= length && length <= MLK_KECCAK_LANES * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
requires(memory_no_alias(data0, length))
/* Case 1: all input buffers are distinct; Case 2: All input buffers are the same */
requires((data0 == data1 &&
data0 == data2 &&
data0 == data3) ||
(memory_no_alias(data1, length) &&
memory_no_alias(data2, length) &&
memory_no_alias(data3, length)))
assigns(memory_slice(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
)
{
mlk_keccakf1600_xor_bytes(state + MLK_KECCAK_LANES * 0, data0, offset,
length);
mlk_keccakf1600_xor_bytes(state + MLK_KECCAK_LANES * 1, data1, offset,
length);
mlk_keccakf1600_xor_bytes(state + MLK_KECCAK_LANES * 2, data2, offset,
length);
mlk_keccakf1600_xor_bytes(state + MLK_KECCAK_LANES * 3, data3, offset,
length);
}
void mlk_keccakf1600x4_xor_bytes(uint64_t *state, const unsigned char *data0,
const unsigned char *data1,
const unsigned char *data2,
const unsigned char *data3, unsigned offset,
unsigned length)
{
#if defined(MLK_USE_FIPS202_X4_XOR_BYTES_NATIVE)
if (mlk_keccakf1600_xor_bytes_x4_native(state, data0, data1, data2, data3,
offset,
length) == MLK_NATIVE_FUNC_SUCCESS)
{
return;
}
#endif /* MLK_USE_FIPS202_X4_XOR_BYTES_NATIVE */
mlk_keccakf1600x4_xor_bytes_c(state, data0, data1, data2, data3, offset,
length);
}
void mlk_keccakf1600x4_permute(uint64_t *state)
{
#if defined(MLK_USE_FIPS202_X4_NATIVE)
if (mlk_keccak_f1600_x4_native(state) == MLK_NATIVE_FUNC_SUCCESS)
{
return;
}
#endif /* MLK_USE_FIPS202_X4_NATIVE */
mlk_keccakf1600_permute(state + MLK_KECCAK_LANES * 0);
mlk_keccakf1600_permute(state + MLK_KECCAK_LANES * 1);
mlk_keccakf1600_permute(state + MLK_KECCAK_LANES * 2);
mlk_keccakf1600_permute(state + MLK_KECCAK_LANES * 3);
}
static const uint64_t mlk_KeccakF_RoundConstants[MLK_KECCAK_NROUNDS] = {
(uint64_t)0x0000000000000001ULL, (uint64_t)0x0000000000008082ULL,
(uint64_t)0x800000000000808aULL, (uint64_t)0x8000000080008000ULL,
(uint64_t)0x000000000000808bULL, (uint64_t)0x0000000080000001ULL,
(uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008009ULL,
(uint64_t)0x000000000000008aULL, (uint64_t)0x0000000000000088ULL,
(uint64_t)0x0000000080008009ULL, (uint64_t)0x000000008000000aULL,
(uint64_t)0x000000008000808bULL, (uint64_t)0x800000000000008bULL,
(uint64_t)0x8000000000008089ULL, (uint64_t)0x8000000000008003ULL,
(uint64_t)0x8000000000008002ULL, (uint64_t)0x8000000000000080ULL,
(uint64_t)0x000000000000800aULL, (uint64_t)0x800000008000000aULL,
(uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008080ULL,
(uint64_t)0x0000000080000001ULL, (uint64_t)0x8000000080008008ULL};
MLK_STATIC_TESTABLE
void mlk_keccakf1600_permute_c(uint64_t *state)
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
assigns(memory_slice(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
)
{
unsigned round;
uint64_t Aba, Abe, Abi, Abo, Abu;
uint64_t Aga, Age, Agi, Ago, Agu;
uint64_t Aka, Ake, Aki, Ako, Aku;
uint64_t Ama, Ame, Ami, Amo, Amu;
uint64_t Asa, Ase, Asi, Aso, Asu;
uint64_t BCa, BCe, BCi, BCo, BCu;
uint64_t Da, De, Di, Do, Du;
uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
uint64_t Ega, Ege, Egi, Ego, Egu;
uint64_t Eka, Eke, Eki, Eko, Eku;
uint64_t Ema, Eme, Emi, Emo, Emu;
uint64_t Esa, Ese, Esi, Eso, Esu;
/* copyFromState(A, state) */
Aba = state[0];
Abe = state[1];
Abi = state[2];
Abo = state[3];
Abu = state[4];
Aga = state[5];
Age = state[6];
Agi = state[7];
Ago = state[8];
Agu = state[9];
Aka = state[10];
Ake = state[11];
Aki = state[12];
Ako = state[13];
Aku = state[14];
Ama = state[15];
Ame = state[16];
Ami = state[17];
Amo = state[18];
Amu = state[19];
Asa = state[20];
Ase = state[21];
Asi = state[22];
Aso = state[23];
Asu = state[24];
for (round = 0; round < MLK_KECCAK_NROUNDS; round += 2)
__loop__(invariant(round <= MLK_KECCAK_NROUNDS && round % 2 == 0)
decreases(MLK_KECCAK_NROUNDS - round))
{
/* prepareTheta */
BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
/* thetaRhoPiChiIotaPrepareTheta(round, A, E) */
Da = BCu ^ MLK_KECCAK_ROL(BCe, 1);
De = BCa ^ MLK_KECCAK_ROL(BCi, 1);
Di = BCe ^ MLK_KECCAK_ROL(BCo, 1);
Do = BCi ^ MLK_KECCAK_ROL(BCu, 1);
Du = BCo ^ MLK_KECCAK_ROL(BCa, 1);
Aba ^= Da;
BCa = Aba;
Age ^= De;
BCe = MLK_KECCAK_ROL(Age, 44);
Aki ^= Di;
BCi = MLK_KECCAK_ROL(Aki, 43);
Amo ^= Do;
BCo = MLK_KECCAK_ROL(Amo, 21);
Asu ^= Du;
BCu = MLK_KECCAK_ROL(Asu, 14);
Eba = BCa ^ ((~BCe) & BCi);
Eba ^= (uint64_t)mlk_KeccakF_RoundConstants[round];
Ebe = BCe ^ ((~BCi) & BCo);
Ebi = BCi ^ ((~BCo) & BCu);
Ebo = BCo ^ ((~BCu) & BCa);
Ebu = BCu ^ ((~BCa) & BCe);
Abo ^= Do;
BCa = MLK_KECCAK_ROL(Abo, 28);
Agu ^= Du;
BCe = MLK_KECCAK_ROL(Agu, 20);
Aka ^= Da;
BCi = MLK_KECCAK_ROL(Aka, 3);
Ame ^= De;
BCo = MLK_KECCAK_ROL(Ame, 45);
Asi ^= Di;
BCu = MLK_KECCAK_ROL(Asi, 61);
Ega = BCa ^ ((~BCe) & BCi);
Ege = BCe ^ ((~BCi) & BCo);
Egi = BCi ^ ((~BCo) & BCu);
Ego = BCo ^ ((~BCu) & BCa);
Egu = BCu ^ ((~BCa) & BCe);
Abe ^= De;
BCa = MLK_KECCAK_ROL(Abe, 1);
Agi ^= Di;
BCe = MLK_KECCAK_ROL(Agi, 6);
Ako ^= Do;
BCi = MLK_KECCAK_ROL(Ako, 25);
Amu ^= Du;
BCo = MLK_KECCAK_ROL(Amu, 8);
Asa ^= Da;
BCu = MLK_KECCAK_ROL(Asa, 18);
Eka = BCa ^ ((~BCe) & BCi);
Eke = BCe ^ ((~BCi) & BCo);
Eki = BCi ^ ((~BCo) & BCu);
Eko = BCo ^ ((~BCu) & BCa);
Eku = BCu ^ ((~BCa) & BCe);
Abu ^= Du;
BCa = MLK_KECCAK_ROL(Abu, 27);
Aga ^= Da;
BCe = MLK_KECCAK_ROL(Aga, 36);
Ake ^= De;
BCi = MLK_KECCAK_ROL(Ake, 10);
Ami ^= Di;
BCo = MLK_KECCAK_ROL(Ami, 15);
Aso ^= Do;
BCu = MLK_KECCAK_ROL(Aso, 56);
Ema = BCa ^ ((~BCe) & BCi);
Eme = BCe ^ ((~BCi) & BCo);
Emi = BCi ^ ((~BCo) & BCu);
Emo = BCo ^ ((~BCu) & BCa);
Emu = BCu ^ ((~BCa) & BCe);
Abi ^= Di;
BCa = MLK_KECCAK_ROL(Abi, 62);
Ago ^= Do;
BCe = MLK_KECCAK_ROL(Ago, 55);
Aku ^= Du;
BCi = MLK_KECCAK_ROL(Aku, 39);
Ama ^= Da;
BCo = MLK_KECCAK_ROL(Ama, 41);
Ase ^= De;
BCu = MLK_KECCAK_ROL(Ase, 2);
Esa = BCa ^ ((~BCe) & BCi);
Ese = BCe ^ ((~BCi) & BCo);
Esi = BCi ^ ((~BCo) & BCu);
Eso = BCo ^ ((~BCu) & BCa);
Esu = BCu ^ ((~BCa) & BCe);
/* prepareTheta */
BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
/* thetaRhoPiChiIotaPrepareTheta(round+1, E, A) */
Da = BCu ^ MLK_KECCAK_ROL(BCe, 1);
De = BCa ^ MLK_KECCAK_ROL(BCi, 1);
Di = BCe ^ MLK_KECCAK_ROL(BCo, 1);
Do = BCi ^ MLK_KECCAK_ROL(BCu, 1);
Du = BCo ^ MLK_KECCAK_ROL(BCa, 1);
Eba ^= Da;
BCa = Eba;
Ege ^= De;
BCe = MLK_KECCAK_ROL(Ege, 44);
Eki ^= Di;
BCi = MLK_KECCAK_ROL(Eki, 43);
Emo ^= Do;
BCo = MLK_KECCAK_ROL(Emo, 21);
Esu ^= Du;
BCu = MLK_KECCAK_ROL(Esu, 14);
Aba = BCa ^ ((~BCe) & BCi);
Aba ^= (uint64_t)mlk_KeccakF_RoundConstants[round + 1];
Abe = BCe ^ ((~BCi) & BCo);
Abi = BCi ^ ((~BCo) & BCu);
Abo = BCo ^ ((~BCu) & BCa);
Abu = BCu ^ ((~BCa) & BCe);
Ebo ^= Do;
BCa = MLK_KECCAK_ROL(Ebo, 28);
Egu ^= Du;
BCe = MLK_KECCAK_ROL(Egu, 20);
Eka ^= Da;
BCi = MLK_KECCAK_ROL(Eka, 3);
Eme ^= De;
BCo = MLK_KECCAK_ROL(Eme, 45);
Esi ^= Di;
BCu = MLK_KECCAK_ROL(Esi, 61);
Aga = BCa ^ ((~BCe) & BCi);
Age = BCe ^ ((~BCi) & BCo);
Agi = BCi ^ ((~BCo) & BCu);
Ago = BCo ^ ((~BCu) & BCa);
Agu = BCu ^ ((~BCa) & BCe);
Ebe ^= De;
BCa = MLK_KECCAK_ROL(Ebe, 1);
Egi ^= Di;
BCe = MLK_KECCAK_ROL(Egi, 6);
Eko ^= Do;
BCi = MLK_KECCAK_ROL(Eko, 25);
Emu ^= Du;
BCo = MLK_KECCAK_ROL(Emu, 8);
Esa ^= Da;
BCu = MLK_KECCAK_ROL(Esa, 18);
Aka = BCa ^ ((~BCe) & BCi);
Ake = BCe ^ ((~BCi) & BCo);
Aki = BCi ^ ((~BCo) & BCu);
Ako = BCo ^ ((~BCu) & BCa);
Aku = BCu ^ ((~BCa) & BCe);
Ebu ^= Du;
BCa = MLK_KECCAK_ROL(Ebu, 27);
Ega ^= Da;
BCe = MLK_KECCAK_ROL(Ega, 36);
Eke ^= De;
BCi = MLK_KECCAK_ROL(Eke, 10);
Emi ^= Di;
BCo = MLK_KECCAK_ROL(Emi, 15);
Eso ^= Do;
BCu = MLK_KECCAK_ROL(Eso, 56);
Ama = BCa ^ ((~BCe) & BCi);
Ame = BCe ^ ((~BCi) & BCo);
Ami = BCi ^ ((~BCo) & BCu);
Amo = BCo ^ ((~BCu) & BCa);
Amu = BCu ^ ((~BCa) & BCe);
Ebi ^= Di;
BCa = MLK_KECCAK_ROL(Ebi, 62);
Ego ^= Do;
BCe = MLK_KECCAK_ROL(Ego, 55);
Eku ^= Du;
BCi = MLK_KECCAK_ROL(Eku, 39);
Ema ^= Da;
BCo = MLK_KECCAK_ROL(Ema, 41);
Ese ^= De;
BCu = MLK_KECCAK_ROL(Ese, 2);
Asa = BCa ^ ((~BCe) & BCi);
Ase = BCe ^ ((~BCi) & BCo);
Asi = BCi ^ ((~BCo) & BCu);
Aso = BCo ^ ((~BCu) & BCa);
Asu = BCu ^ ((~BCa) & BCe);
}
/* copyToState(state, A) */
state[0] = Aba;
state[1] = Abe;
state[2] = Abi;
state[3] = Abo;
state[4] = Abu;
state[5] = Aga;
state[6] = Age;
state[7] = Agi;
state[8] = Ago;
state[9] = Agu;
state[10] = Aka;
state[11] = Ake;
state[12] = Aki;
state[13] = Ako;
state[14] = Aku;
state[15] = Ama;
state[16] = Ame;
state[17] = Ami;
state[18] = Amo;
state[19] = Amu;
state[20] = Asa;
state[21] = Ase;
state[22] = Asi;
state[23] = Aso;
state[24] = Asu;
}
void mlk_keccakf1600_permute(uint64_t *state)
{
#if defined(MLK_USE_FIPS202_X1_NATIVE)
if (mlk_keccak_f1600_x1_native(state) == MLK_NATIVE_FUNC_SUCCESS)
{
return;
}
#endif /* MLK_USE_FIPS202_X1_NATIVE */
mlk_keccakf1600_permute_c(state);
}
#else /* !MLK_CONFIG_MULTILEVEL_NO_SHARED */
MLK_EMPTY_CU(keccakf1600)
#endif /* MLK_CONFIG_MULTILEVEL_NO_SHARED */
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
* Don't modify by hand -- this is auto-generated by scripts/autogen. */
#undef MLK_KECCAK_NROUNDS
#undef MLK_KECCAK_ROL

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_KECCAKF1600_H
#define MLK_FIPS202_KECCAKF1600_H
#include "../cbmc.h"
#include "../common.h"
#define MLK_KECCAK_LANES 25
#define MLK_KECCAK_WAY 4
/*
* WARNING:
* The contents of this structure, including the placement
* and interleaving of Keccak lanes, are IMPLEMENTATION-DEFINED.
* The struct is only exposed here to allow its construction on the stack.
*/
#define mlk_keccakf1600_extract_bytes MLK_NAMESPACE(keccakf1600_extract_bytes)
void mlk_keccakf1600_extract_bytes(uint64_t *state, unsigned char *data,
unsigned offset, unsigned length)
__contract__(
requires(0 <= offset && offset <= MLK_KECCAK_LANES * sizeof(uint64_t) &&
0 <= length && length <= MLK_KECCAK_LANES * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
requires(memory_no_alias(data, length))
assigns(memory_slice(data, length))
);
#define mlk_keccakf1600_xor_bytes MLK_NAMESPACE(keccakf1600_xor_bytes)
void mlk_keccakf1600_xor_bytes(uint64_t *state, const unsigned char *data,
unsigned offset, unsigned length)
__contract__(
requires(0 <= offset && offset <= MLK_KECCAK_LANES * sizeof(uint64_t) &&
0 <= length && length <= MLK_KECCAK_LANES * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
requires(memory_no_alias(data, length))
assigns(memory_slice(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
);
#define mlk_keccakf1600x4_extract_bytes \
MLK_NAMESPACE(keccakf1600x4_extract_bytes)
void mlk_keccakf1600x4_extract_bytes(uint64_t *state, unsigned char *data0,
unsigned char *data1, unsigned char *data2,
unsigned char *data3, unsigned offset,
unsigned length)
__contract__(
requires(0 <= offset && offset <= MLK_KECCAK_LANES * sizeof(uint64_t) &&
0 <= length && length <= MLK_KECCAK_LANES * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
requires(memory_no_alias(data0, length))
requires(memory_no_alias(data1, length))
requires(memory_no_alias(data2, length))
requires(memory_no_alias(data3, length))
assigns(memory_slice(data0, length))
assigns(memory_slice(data1, length))
assigns(memory_slice(data2, length))
assigns(memory_slice(data3, length))
);
#define mlk_keccakf1600x4_xor_bytes MLK_NAMESPACE(keccakf1600x4_xor_bytes)
void mlk_keccakf1600x4_xor_bytes(uint64_t *state, const unsigned char *data0,
const unsigned char *data1,
const unsigned char *data2,
const unsigned char *data3, unsigned offset,
unsigned length)
__contract__(
requires(0 <= offset && offset <= MLK_KECCAK_LANES * sizeof(uint64_t) &&
0 <= length && length <= MLK_KECCAK_LANES * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
requires(memory_no_alias(data0, length))
/* Case 1: all input buffers are distinct; Case 2: All input buffers are the same */
requires((data0 == data1 &&
data0 == data2 &&
data0 == data3) ||
(memory_no_alias(data1, length) &&
memory_no_alias(data2, length) &&
memory_no_alias(data3, length)))
assigns(memory_slice(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
);
#define mlk_keccakf1600x4_permute MLK_NAMESPACE(keccakf1600x4_permute)
void mlk_keccakf1600x4_permute(uint64_t *state)
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
assigns(memory_slice(state, sizeof(uint64_t) * MLK_KECCAK_LANES * MLK_KECCAK_WAY))
);
#define mlk_keccakf1600_permute MLK_NAMESPACE(keccakf1600_permute)
void mlk_keccakf1600_permute(uint64_t *state)
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
assigns(memory_slice(state, sizeof(uint64_t) * MLK_KECCAK_LANES))
);
#endif /* !MLK_FIPS202_KECCAKF1600_H */

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [HYBRID]
* Hybrid scalar/vector implementations of Keccak and SPHINCS+ on AArch64
* Becker, Kannwischer
* https://eprint.iacr.org/2022/1243
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_AUTO_H
#define MLK_FIPS202_NATIVE_AARCH64_AUTO_H
/* Default FIPS202 assembly profile for AArch64 systems */
/*
* Default logic to decide which implementation to use.
*
*/
/*
* Keccak-f1600
*
* - On Arm-based Apple CPUs, we pick a pure Neon implementation.
* - Otherwise, unless MLK_SYS_AARCH64_SLOW_BARREL_SHIFTER is set,
* we use lazy-rotation scalar assembly from @[HYBRID].
* - Otherwise, if MLK_SYS_AARCH64_SLOW_BARREL_SHIFTER is set, we
* fall back to the standard C implementation.
*/
#if defined(__ARM_FEATURE_SHA3) && defined(__APPLE__)
#include "x1_v84a.h"
#elif !defined(MLK_SYS_AARCH64_SLOW_BARREL_SHIFTER)
#include "x1_scalar.h"
#endif
/*
* Keccak-f1600x2/x4
*
* The optimal implementation is highly CPU-specific; see @[HYBRID].
*
* For now, if v8.4-A is not implemented, we fall back to Keccak-f1600.
* If v8.4-A is implemented and we are on an Apple CPU, we use a plain
* Neon-based implementation.
* If v8.4-A is implemented and we are not on an Apple CPU, we use a
* scalar/Neon/Neon hybrid.
* The reason for this distinction is that Apple CPUs appear to implement
* the SHA3 instructions on all SIMD units, while Arm CPUs prior to Cortex-X4
* don't, and ordinary Neon instructions are still needed.
*/
#if defined(__ARM_FEATURE_SHA3)
/*
* For Apple-M cores, we use a plain implementation leveraging SHA3
* instructions only.
*/
#if defined(__APPLE__)
#include "x2_v84a.h"
#else
#include "x4_v8a_v84a_scalar.h"
#endif
#else /* __ARM_FEATURE_SHA3 */
#include "x4_v8a_scalar.h"
#endif /* !__ARM_FEATURE_SHA3 */
#endif /* !MLK_FIPS202_NATIVE_AARCH64_AUTO_H */

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_SRC_FIPS202_NATIVE_AARCH64_H
#define MLK_FIPS202_NATIVE_AARCH64_SRC_FIPS202_NATIVE_AARCH64_H
#include "../../../../cbmc.h"
#include "../../../../common.h"
#define mlk_keccakf1600_round_constants \
MLK_NAMESPACE(keccakf1600_round_constants)
MLK_INTERNAL_DATA_DECLARATION const uint64_t
mlk_keccakf1600_round_constants[24];
#define mlk_keccak_f1600_x1_scalar_aarch64_asm \
MLK_NAMESPACE(keccak_f1600_x1_scalar_aarch64_asm)
void mlk_keccak_f1600_x1_scalar_aarch64_asm(uint64_t state[25],
const uint64_t rc[24])
/* This must be kept in sync with the HOL-Light specification
* in proofs/hol_light/aarch64/proofs/keccak_f1600_x1_scalar_aarch64_asm.ml */
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 1))
requires(rc == mlk_keccakf1600_round_constants)
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 1))
);
#define mlk_keccak_f1600_x1_v84a_aarch64_asm \
MLK_NAMESPACE(keccak_f1600_x1_v84a_aarch64_asm)
void mlk_keccak_f1600_x1_v84a_aarch64_asm(uint64_t state[25],
const uint64_t rc[24])
/* This must be kept in sync with the HOL-Light specification
* in proofs/hol_light/aarch64/proofs/keccak_f1600_x1_v84a_aarch64_asm.ml */
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 1))
requires(rc == mlk_keccakf1600_round_constants)
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 1))
);
#define mlk_keccak_f1600_x2_v84a_aarch64_asm \
MLK_NAMESPACE(keccak_f1600_x2_v84a_aarch64_asm)
void mlk_keccak_f1600_x2_v84a_aarch64_asm(uint64_t state[50],
const uint64_t rc[24])
/* This must be kept in sync with the HOL-Light specification
* in proofs/hol_light/aarch64/proofs/keccak_f1600_x2_v84a_aarch64_asm.ml */
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 2))
requires(rc == mlk_keccakf1600_round_constants)
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 2))
);
#define mlk_keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm \
MLK_NAMESPACE(keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm)
void mlk_keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm(uint64_t state[100],
const uint64_t rc[24])
/* This must be kept in sync with the HOL-Light specification
* in
* proofs/hol_light/aarch64/proofs/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.ml
*/
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 4))
requires(rc == mlk_keccakf1600_round_constants)
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 4))
);
#define mlk_keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm \
MLK_NAMESPACE(keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm)
void mlk_keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm(
uint64_t state[100], const uint64_t rc[24])
/* This must be kept in sync with the HOL-Light specification
* in
* proofs/hol_light/aarch64/proofs/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.ml
*/
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 4))
requires(rc == mlk_keccakf1600_round_constants)
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 4))
);
#endif /* !MLK_FIPS202_NATIVE_AARCH64_SRC_FIPS202_NATIVE_AARCH64_H */

View File

@@ -0,0 +1,377 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) 2021-2022 Arm Limited
* Copyright (c) 2022 Matthias Kannwischer
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
// Author: Hanno Becker <hanno.becker@arm.com>
// Author: Matthias Kannwischer <matthias@kannwischer.eu>
/*yaml
Name: keccak_f1600_x1_scalar_aarch64_asm
Description: AArch64 scalar implementation of Keccak-f[1600] permutation for single state
Signature: void mlk_keccak_f1600_x1_scalar_aarch64_asm(uint64_t state[25], const uint64_t rc[24])
ABI:
Architecture: aarch64
CallingConvention: AAPCS64
x0:
type: buffer
size_bytes: 200
permissions: read/write
c_parameter: uint64_t state[25]
description: Keccak state (25 x uint64_t)
x1:
type: buffer
size_bytes: 192
permissions: read-only
c_parameter: uint64_t const *rc
description: Round constants (24 x uint64_t)
Stack:
bytes: 128
description: register preservation and temporary storage
*/
#include "../../../../common.h"
#if defined(MLK_FIPS202_AARCH64_NEED_X1_SCALAR) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S using scripts/simpasm. Do not modify it directly.
*/
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x1_scalar_aarch64_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x1_scalar_aarch64_asm)
.cfi_startproc
sub sp, sp, #0x80
.cfi_adjust_cfa_offset 0x80
stp x19, x20, [sp, #0x20]
.cfi_rel_offset x19, 0x20
.cfi_rel_offset x20, 0x28
stp x21, x22, [sp, #0x30]
.cfi_rel_offset x21, 0x30
.cfi_rel_offset x22, 0x38
stp x23, x24, [sp, #0x40]
.cfi_rel_offset x23, 0x40
.cfi_rel_offset x24, 0x48
stp x25, x26, [sp, #0x50]
.cfi_rel_offset x25, 0x50
.cfi_rel_offset x26, 0x58
stp x27, x28, [sp, #0x60]
.cfi_rel_offset x27, 0x60
.cfi_rel_offset x28, 0x68
stp x29, x30, [sp, #0x70]
.cfi_rel_offset x29, 0x70
.cfi_rel_offset x30, 0x78
Lkeccak_f1600_x1_scalar_initial:
mov x26, x1
str x1, [sp, #0x8]
ldp x1, x6, [x0]
ldp x11, x16, [x0, #0x10]
ldp x21, x2, [x0, #0x20]
ldp x7, x12, [x0, #0x30]
ldp x17, x22, [x0, #0x40]
ldp x3, x8, [x0, #0x50]
ldp x13, x28, [x0, #0x60]
ldp x23, x4, [x0, #0x70]
ldp x9, x14, [x0, #0x80]
ldp x19, x24, [x0, #0x90]
ldp x5, x10, [x0, #0xa0]
ldp x15, x20, [x0, #0xb0]
ldr x25, [x0, #0xc0]
str x0, [sp]
eor x30, x24, x25
eor x27, x9, x10
eor x0, x30, x21
eor x26, x27, x6
eor x27, x26, x7
eor x29, x0, x22
eor x26, x29, x23
eor x29, x4, x5
eor x30, x29, x1
eor x0, x27, x8
eor x29, x30, x2
eor x30, x19, x20
eor x30, x30, x16
eor x27, x26, x0, ror #63
eor x4, x4, x27
eor x30, x30, x17
eor x30, x30, x28
eor x29, x29, x3
eor x0, x0, x30, ror #63
eor x30, x30, x29, ror #63
eor x22, x22, x30
eor x23, x23, x30
str x23, [sp, #0x18]
eor x23, x14, x15
eor x14, x14, x0
eor x23, x23, x11
eor x15, x15, x0
eor x1, x1, x27
eor x23, x23, x12
eor x23, x23, x13
eor x11, x11, x0
eor x29, x29, x23, ror #63
eor x23, x23, x26, ror #63
eor x26, x13, x0
eor x13, x28, x23
eor x28, x24, x30
eor x24, x16, x23
eor x16, x21, x30
eor x21, x25, x30
eor x30, x19, x23
eor x19, x20, x23
eor x20, x17, x23
eor x17, x12, x0
eor x0, x2, x27
eor x2, x6, x29
eor x6, x8, x29
bic x8, x28, x13, ror #47
eor x12, x3, x27
bic x3, x13, x17, ror #19
eor x5, x5, x27
ldr x27, [sp, #0x18]
bic x25, x17, x2, ror #5
eor x9, x9, x29
eor x23, x25, x5, ror #52
eor x3, x3, x2, ror #24
eor x8, x8, x17, ror #2
eor x17, x10, x29
bic x25, x12, x22, ror #47
eor x29, x7, x29
bic x10, x4, x27, ror #2
bic x7, x5, x28, ror #10
eor x10, x10, x20, ror #50
eor x13, x7, x13, ror #57
bic x7, x2, x5, ror #47
eor x2, x25, x24, ror #39
bic x25, x20, x11, ror #57
bic x5, x17, x4, ror #25
eor x25, x25, x17, ror #53
bic x17, x11, x17, ror #60
eor x28, x7, x28, ror #57
bic x7, x9, x12, ror #42
eor x7, x7, x22, ror #25
bic x22, x22, x24, ror #56
bic x24, x24, x15, ror #31
eor x22, x22, x15, ror #23
bic x20, x27, x20, ror #48
bic x15, x15, x9, ror #16
eor x12, x15, x12, ror #58
eor x15, x5, x27, ror #27
eor x5, x20, x11, ror #41
ldr x11, [sp, #0x8]
eor x20, x17, x4, ror #21
eor x17, x24, x9, ror #47
mov x24, #0x1 // =1
bic x9, x0, x16, ror #9
str x24, [sp, #0x10]
bic x24, x29, x1, ror #44
bic x27, x1, x21, ror #50
bic x4, x26, x29, ror #63
eor x1, x1, x4, ror #21
ldr x11, [x11]
bic x4, x21, x30, ror #57
eor x21, x24, x21, ror #30
eor x24, x9, x19, ror #44
bic x9, x14, x6, ror #5
eor x9, x9, x0, ror #43
bic x0, x6, x0, ror #38
eor x1, x1, x11
eor x11, x4, x26, ror #35
eor x4, x0, x16, ror #47
bic x0, x16, x19, ror #35
eor x16, x27, x30, ror #43
bic x27, x30, x26, ror #42
bic x26, x19, x14, ror #41
eor x19, x0, x14, ror #12
eor x14, x26, x6, ror #46
eor x6, x27, x29, ror #41
Lkeccak_f1600_x1_scalar_loop:
eor x0, x15, x11, ror #52
eor x0, x0, x13, ror #48
eor x26, x8, x9, ror #57
eor x27, x0, x14, ror #10
eor x29, x16, x28, ror #63
eor x26, x26, x6, ror #51
eor x30, x23, x22, ror #50
eor x0, x26, x10, ror #31
eor x29, x29, x19, ror #37
eor x27, x27, x12, ror #5
eor x30, x30, x24, ror #34
eor x0, x0, x7, ror #27
eor x26, x30, x21, ror #26
eor x26, x26, x25, ror #15
ror x30, x27, #0x3e
eor x30, x30, x26, ror #57
ror x26, x26, #0x3a
eor x16, x30, x16
eor x28, x30, x28, ror #63
str x28, [sp, #0x18]
eor x29, x29, x17, ror #36
eor x28, x1, x2, ror #61
eor x19, x30, x19, ror #37
eor x29, x29, x20, ror #2
eor x28, x28, x4, ror #54
eor x26, x26, x0, ror #55
eor x28, x28, x3, ror #39
eor x28, x28, x5, ror #25
ror x0, x0, #0x38
eor x0, x0, x29, ror #63
eor x27, x28, x27, ror #61
eor x13, x0, x13, ror #46
eor x28, x29, x28, ror #63
eor x29, x30, x20, ror #2
eor x20, x26, x3, ror #39
eor x11, x0, x11, ror #50
eor x25, x28, x25, ror #9
eor x3, x28, x21, ror #20
eor x21, x26, x1
eor x9, x27, x9, ror #49
eor x24, x28, x24, ror #28
eor x1, x30, x17, ror #36
eor x14, x0, x14, ror #8
eor x22, x28, x22, ror #44
eor x8, x27, x8, ror #56
eor x17, x27, x7, ror #19
eor x15, x0, x15, ror #62
bic x7, x20, x22, ror #47
eor x4, x26, x4, ror #54
eor x0, x0, x12, ror #3
eor x28, x28, x23, ror #58
eor x23, x26, x2, ror #61
eor x26, x26, x5, ror #25
eor x2, x7, x16, ror #39
bic x7, x9, x20, ror #42
bic x30, x15, x9, ror #16
eor x7, x7, x22, ror #25
eor x12, x30, x20, ror #58
bic x20, x22, x16, ror #56
eor x30, x27, x6, ror #43
eor x22, x20, x15, ror #23
bic x6, x19, x13, ror #42
eor x6, x6, x17, ror #41
bic x5, x13, x17, ror #63
eor x5, x21, x5, ror #21
bic x17, x17, x21, ror #44
eor x27, x27, x10, ror #23
bic x21, x21, x25, ror #50
bic x20, x27, x4, ror #25
bic x10, x16, x15, ror #31
eor x16, x21, x19, ror #43
eor x21, x17, x25, ror #30
bic x19, x25, x19, ror #57
ldr x25, [sp, #0x10]
eor x17, x10, x9, ror #47
ldr x9, [sp, #0x8]
eor x15, x20, x28, ror #27
bic x20, x4, x28, ror #2
eor x10, x20, x1, ror #50
bic x20, x11, x27, ror #60
eor x20, x20, x4, ror #21
bic x4, x28, x1, ror #48
bic x1, x1, x11, ror #57
ldr x28, [x9, x25, lsl #3]
ldr x9, [sp, #0x18]
add x25, x25, #0x1
str x25, [sp, #0x10]
cmp x25, #0x17
eor x25, x1, x27, ror #53
bic x27, x30, x26, ror #47
eor x1, x5, x28
eor x5, x4, x11, ror #41
eor x11, x19, x13, ror #35
bic x13, x26, x24, ror #10
eor x28, x27, x24, ror #57
bic x27, x24, x9, ror #47
bic x19, x23, x3, ror #9
bic x4, x29, x14, ror #41
eor x24, x19, x29, ror #44
bic x29, x3, x29, ror #35
eor x13, x13, x9, ror #57
eor x19, x29, x14, ror #12
bic x29, x9, x0, ror #19
bic x14, x14, x8, ror #5
eor x9, x14, x23, ror #43
eor x14, x4, x8, ror #46
bic x23, x8, x23, ror #38
eor x8, x27, x0, ror #2
eor x4, x23, x3, ror #47
bic x3, x0, x30, ror #5
eor x23, x3, x26, ror #52
eor x3, x29, x30, ror #24
b.le Lkeccak_f1600_x1_scalar_loop
ror x6, x6, #0x2b
ror x11, x11, #0x32
ror x21, x21, #0x14
ror x2, x2, #0x3d
ror x7, x7, #0x13
ror x12, x12, #0x3
ror x17, x17, #0x24
ror x22, x22, #0x2c
ror x3, x3, #0x27
ror x8, x8, #0x38
ror x13, x13, #0x2e
ror x28, x28, #0x3f
ror x23, x23, #0x3a
ror x4, x4, #0x36
ror x9, x9, #0x31
ror x14, x14, #0x8
ror x19, x19, #0x25
ror x24, x24, #0x1c
ror x5, x5, #0x19
ror x10, x10, #0x17
ror x15, x15, #0x3e
ror x20, x20, #0x2
ror x25, x25, #0x9
ldr x0, [sp]
stp x1, x6, [x0]
stp x11, x16, [x0, #0x10]
stp x21, x2, [x0, #0x20]
stp x7, x12, [x0, #0x30]
stp x17, x22, [x0, #0x40]
stp x3, x8, [x0, #0x50]
stp x13, x28, [x0, #0x60]
stp x23, x4, [x0, #0x70]
stp x9, x14, [x0, #0x80]
stp x19, x24, [x0, #0x90]
stp x5, x10, [x0, #0xa0]
stp x15, x20, [x0, #0xb0]
str x25, [x0, #0xc0]
ldp x19, x20, [sp, #0x20]
.cfi_restore x19
.cfi_restore x20
ldp x21, x22, [sp, #0x30]
.cfi_restore x21
.cfi_restore x22
ldp x23, x24, [sp, #0x40]
.cfi_restore x23
.cfi_restore x24
ldp x25, x26, [sp, #0x50]
.cfi_restore x25
.cfi_restore x26
ldp x27, x28, [sp, #0x60]
.cfi_restore x27
.cfi_restore x28
ldp x29, x30, [sp, #0x70]
.cfi_restore x29
.cfi_restore x30
add sp, sp, #0x80
.cfi_adjust_cfa_offset -0x80
ret
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x1_scalar_aarch64_asm)
#endif /* MLK_FIPS202_AARCH64_NEED_X1_SCALAR && \
!MLK_CONFIG_MULTILEVEL_NO_SHARED */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,206 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) 2021-2022 Arm Limited
* Copyright (c) 2022 Matthias Kannwischer
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [HYBRID]
* Hybrid scalar/vector implementations of Keccak and SPHINCS+ on AArch64
* Becker, Kannwischer
* https://eprint.iacr.org/2022/1243
*/
/*yaml
Name: keccak_f1600_x1_v84a_aarch64_asm
Description: AArch64 ARMv8.4-A implementation of Keccak-f[1600] permutation for single state
Signature: void mlk_keccak_f1600_x1_v84a_aarch64_asm(uint64_t state[25], const uint64_t rc[24])
ABI:
Architecture: aarch64
CallingConvention: AAPCS64
Features: [SHA3]
x0:
type: buffer
size_bytes: 200
permissions: read/write
c_parameter: uint64_t state[25]
description: Keccak state (25 x uint64_t)
x1:
type: buffer
size_bytes: 192
permissions: read-only
c_parameter: const uint64_t rc[24]
description: Round constants (24 x uint64_t)
Stack:
bytes: 64
description: register preservation
*/
//
// Author: Hanno Becker <hanno.becker@arm.com>
// Author: Matthias Kannwischer <matthias@kannwischer.eu>
//
// This implementation is essentially from the paper @[HYBRID].
// The only difference is interleaving/deinterleaving of Keccak state
// during load and store, so that the caller need not do this.
//
#include "../../../../common.h"
#if defined(MLK_FIPS202_AARCH64_NEED_X1_V84A) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#if defined(__ARM_FEATURE_SHA3)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S using scripts/simpasm. Do not modify it directly.
*/
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x1_v84a_aarch64_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x1_v84a_aarch64_asm)
.cfi_startproc
sub sp, sp, #0x40
.cfi_adjust_cfa_offset 0x40
stp d8, d9, [sp]
.cfi_rel_offset d8, 0x0
.cfi_rel_offset d9, 0x8
stp d10, d11, [sp, #0x10]
.cfi_rel_offset d10, 0x10
.cfi_rel_offset d11, 0x18
stp d12, d13, [sp, #0x20]
.cfi_rel_offset d12, 0x20
.cfi_rel_offset d13, 0x28
stp d14, d15, [sp, #0x30]
.cfi_rel_offset d14, 0x30
.cfi_rel_offset d15, 0x38
ldp d0, d1, [x0]
ldp d2, d3, [x0, #0x10]
ldp d4, d5, [x0, #0x20]
ldp d6, d7, [x0, #0x30]
ldp d8, d9, [x0, #0x40]
ldp d10, d11, [x0, #0x50]
ldp d12, d13, [x0, #0x60]
ldp d14, d15, [x0, #0x70]
ldp d16, d17, [x0, #0x80]
ldp d18, d19, [x0, #0x90]
ldp d20, d21, [x0, #0xa0]
ldp d22, d23, [x0, #0xb0]
ldr d24, [x0, #0xc0]
mov x2, #0x18 // =24
Lkeccak_f1600_x1_v84a_loop:
eor3 v30.16b, v0.16b, v5.16b, v10.16b
eor3 v29.16b, v1.16b, v6.16b, v11.16b
eor3 v28.16b, v2.16b, v7.16b, v12.16b
eor3 v27.16b, v3.16b, v8.16b, v13.16b
eor3 v26.16b, v4.16b, v9.16b, v14.16b
eor3 v30.16b, v30.16b, v15.16b, v20.16b
eor3 v29.16b, v29.16b, v16.16b, v21.16b
eor3 v28.16b, v28.16b, v17.16b, v22.16b
eor3 v27.16b, v27.16b, v18.16b, v23.16b
eor3 v26.16b, v26.16b, v19.16b, v24.16b
rax1 v25.2d, v30.2d, v28.2d
rax1 v28.2d, v28.2d, v26.2d
rax1 v26.2d, v26.2d, v29.2d
rax1 v29.2d, v29.2d, v27.2d
rax1 v27.2d, v27.2d, v30.2d
eor v30.16b, v0.16b, v26.16b
xar v0.2d, v2.2d, v29.2d, #0x2
xar v2.2d, v12.2d, v29.2d, #0x15
xar v12.2d, v13.2d, v28.2d, #0x27
xar v13.2d, v19.2d, v27.2d, #0x38
xar v19.2d, v23.2d, v28.2d, #0x8
xar v23.2d, v15.2d, v26.2d, #0x17
xar v15.2d, v1.2d, v25.2d, #0x3f
xar v1.2d, v8.2d, v28.2d, #0x9
xar v8.2d, v16.2d, v25.2d, #0x13
xar v16.2d, v7.2d, v29.2d, #0x3a
xar v7.2d, v10.2d, v26.2d, #0x3d
xar v10.2d, v3.2d, v28.2d, #0x24
xar v3.2d, v18.2d, v28.2d, #0x2b
xar v18.2d, v17.2d, v29.2d, #0x31
xar v17.2d, v11.2d, v25.2d, #0x36
xar v11.2d, v9.2d, v27.2d, #0x2c
xar v9.2d, v22.2d, v29.2d, #0x3
xar v22.2d, v14.2d, v27.2d, #0x19
xar v14.2d, v20.2d, v26.2d, #0x2e
xar v20.2d, v4.2d, v27.2d, #0x25
xar v4.2d, v24.2d, v27.2d, #0x32
xar v24.2d, v21.2d, v25.2d, #0x3e
xar v21.2d, v5.2d, v26.2d, #0x1c
xar v27.2d, v6.2d, v25.2d, #0x14
ld1r { v31.2d }, [x1], #8
bcax v5.16b, v10.16b, v7.16b, v11.16b
bcax v6.16b, v11.16b, v8.16b, v7.16b
bcax v7.16b, v7.16b, v9.16b, v8.16b
bcax v8.16b, v8.16b, v10.16b, v9.16b
bcax v9.16b, v9.16b, v11.16b, v10.16b
bcax v10.16b, v15.16b, v12.16b, v16.16b
bcax v11.16b, v16.16b, v13.16b, v12.16b
bcax v12.16b, v12.16b, v14.16b, v13.16b
bcax v13.16b, v13.16b, v15.16b, v14.16b
bcax v14.16b, v14.16b, v16.16b, v15.16b
bcax v15.16b, v20.16b, v17.16b, v21.16b
bcax v16.16b, v21.16b, v18.16b, v17.16b
bcax v17.16b, v17.16b, v19.16b, v18.16b
bcax v18.16b, v18.16b, v20.16b, v19.16b
bcax v19.16b, v19.16b, v21.16b, v20.16b
bcax v20.16b, v0.16b, v22.16b, v1.16b
bcax v21.16b, v1.16b, v23.16b, v22.16b
bcax v22.16b, v22.16b, v24.16b, v23.16b
bcax v23.16b, v23.16b, v0.16b, v24.16b
bcax v24.16b, v24.16b, v1.16b, v0.16b
bcax v0.16b, v30.16b, v2.16b, v27.16b
bcax v1.16b, v27.16b, v3.16b, v2.16b
bcax v2.16b, v2.16b, v4.16b, v3.16b
bcax v3.16b, v3.16b, v30.16b, v4.16b
bcax v4.16b, v4.16b, v27.16b, v30.16b
eor v0.16b, v0.16b, v31.16b
sub x2, x2, #0x1
cbnz x2, Lkeccak_f1600_x1_v84a_loop
stp d0, d1, [x0]
stp d2, d3, [x0, #0x10]
stp d4, d5, [x0, #0x20]
stp d6, d7, [x0, #0x30]
stp d8, d9, [x0, #0x40]
stp d10, d11, [x0, #0x50]
stp d12, d13, [x0, #0x60]
stp d14, d15, [x0, #0x70]
stp d16, d17, [x0, #0x80]
stp d18, d19, [x0, #0x90]
stp d20, d21, [x0, #0xa0]
stp d22, d23, [x0, #0xb0]
str d24, [x0, #0xc0]
ldp d8, d9, [sp]
.cfi_restore d8
.cfi_restore d9
ldp d10, d11, [sp, #0x10]
.cfi_restore d10
.cfi_restore d11
ldp d12, d13, [sp, #0x20]
.cfi_restore d12
.cfi_restore d13
ldp d14, d15, [sp, #0x30]
.cfi_restore d14
.cfi_restore d15
add sp, sp, #0x40
.cfi_adjust_cfa_offset -0x40
ret
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x1_v84a_aarch64_asm)
#endif /* __ARM_FEATURE_SHA3 */
#endif /* MLK_FIPS202_AARCH64_NEED_X1_V84A && !MLK_CONFIG_MULTILEVEL_NO_SHARED \
*/
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,261 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) 2021-2022 Arm Limited
* Copyright (c) 2022 Matthias Kannwischer
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/* References
* ==========
*
* - [HYBRID]
* Hybrid scalar/vector implementations of Keccak and SPHINCS+ on AArch64
* Becker, Kannwischer
* https://eprint.iacr.org/2022/1243
*/
/*yaml
Name: keccak_f1600_x2_v84a_aarch64_asm
Description: AArch64 ARMv8.4-A implementation of Keccak-f[1600] permutation for two sequential states
Signature: void mlk_keccak_f1600_x2_v84a_aarch64_asm(uint64_t state[50], const uint64_t rc[24])
ABI:
Architecture: aarch64
CallingConvention: AAPCS64
Features: [SHA3]
x0:
type: buffer
size_bytes: 400
permissions: read/write
c_parameter: uint64_t state[50]
description: Two sequential Keccak states (state0[25], state1[25])
x1:
type: buffer
size_bytes: 192
permissions: read-only
c_parameter: const uint64_t rc[24]
description: Round constants (24 x uint64_t)
Stack:
bytes: 64
description: register preservation
*/
//
// Author: Hanno Becker <hanno.becker@arm.com>
// Author: Matthias Kannwischer <matthias@kannwischer.eu>
//
// This implementation is essentially from the paper @[HYBRID].
// The only difference is interleaving/deinterleaving of Keccak state
// during load and store, so that the caller need not do this.
//
#include "../../../../common.h"
#if defined(MLK_FIPS202_AARCH64_NEED_X2_V84A) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#if defined(__ARM_FEATURE_SHA3)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S using scripts/simpasm. Do not modify it directly.
*/
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x2_v84a_aarch64_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x2_v84a_aarch64_asm)
.cfi_startproc
sub sp, sp, #0x40
.cfi_adjust_cfa_offset 0x40
stp d8, d9, [sp]
.cfi_rel_offset d8, 0x0
.cfi_rel_offset d9, 0x8
stp d10, d11, [sp, #0x10]
.cfi_rel_offset d10, 0x10
.cfi_rel_offset d11, 0x18
stp d12, d13, [sp, #0x20]
.cfi_rel_offset d12, 0x20
.cfi_rel_offset d13, 0x28
stp d14, d15, [sp, #0x30]
.cfi_rel_offset d14, 0x30
.cfi_rel_offset d15, 0x38
add x2, x0, #0xc8
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x2], #32
trn1 v0.2d, v25.2d, v27.2d
trn2 v1.2d, v25.2d, v27.2d
trn1 v2.2d, v26.2d, v28.2d
trn2 v3.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x2], #32
trn1 v4.2d, v25.2d, v27.2d
trn2 v5.2d, v25.2d, v27.2d
trn1 v6.2d, v26.2d, v28.2d
trn2 v7.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x2], #32
trn1 v8.2d, v25.2d, v27.2d
trn2 v9.2d, v25.2d, v27.2d
trn1 v10.2d, v26.2d, v28.2d
trn2 v11.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x2], #32
trn1 v12.2d, v25.2d, v27.2d
trn2 v13.2d, v25.2d, v27.2d
trn1 v14.2d, v26.2d, v28.2d
trn2 v15.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x2], #32
trn1 v16.2d, v25.2d, v27.2d
trn2 v17.2d, v25.2d, v27.2d
trn1 v18.2d, v26.2d, v28.2d
trn2 v19.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x2], #32
trn1 v20.2d, v25.2d, v27.2d
trn2 v21.2d, v25.2d, v27.2d
trn1 v22.2d, v26.2d, v28.2d
trn2 v23.2d, v26.2d, v28.2d
ldr d25, [x0]
ldr d27, [x2]
trn1 v24.2d, v25.2d, v27.2d
mov x2, #0x18 // =24
Lkeccak_f1600_x2_v84a_loop:
eor3 v30.16b, v0.16b, v5.16b, v10.16b
eor3 v29.16b, v1.16b, v6.16b, v11.16b
eor3 v28.16b, v2.16b, v7.16b, v12.16b
eor3 v27.16b, v3.16b, v8.16b, v13.16b
eor3 v26.16b, v4.16b, v9.16b, v14.16b
eor3 v30.16b, v30.16b, v15.16b, v20.16b
eor3 v29.16b, v29.16b, v16.16b, v21.16b
eor3 v28.16b, v28.16b, v17.16b, v22.16b
eor3 v27.16b, v27.16b, v18.16b, v23.16b
eor3 v26.16b, v26.16b, v19.16b, v24.16b
rax1 v25.2d, v30.2d, v28.2d
rax1 v28.2d, v28.2d, v26.2d
rax1 v26.2d, v26.2d, v29.2d
rax1 v29.2d, v29.2d, v27.2d
rax1 v27.2d, v27.2d, v30.2d
eor v30.16b, v0.16b, v26.16b
xar v0.2d, v2.2d, v29.2d, #0x2
xar v2.2d, v12.2d, v29.2d, #0x15
xar v12.2d, v13.2d, v28.2d, #0x27
xar v13.2d, v19.2d, v27.2d, #0x38
xar v19.2d, v23.2d, v28.2d, #0x8
xar v23.2d, v15.2d, v26.2d, #0x17
xar v15.2d, v1.2d, v25.2d, #0x3f
xar v1.2d, v8.2d, v28.2d, #0x9
xar v8.2d, v16.2d, v25.2d, #0x13
xar v16.2d, v7.2d, v29.2d, #0x3a
xar v7.2d, v10.2d, v26.2d, #0x3d
xar v10.2d, v3.2d, v28.2d, #0x24
xar v3.2d, v18.2d, v28.2d, #0x2b
xar v18.2d, v17.2d, v29.2d, #0x31
xar v17.2d, v11.2d, v25.2d, #0x36
xar v11.2d, v9.2d, v27.2d, #0x2c
xar v9.2d, v22.2d, v29.2d, #0x3
xar v22.2d, v14.2d, v27.2d, #0x19
xar v14.2d, v20.2d, v26.2d, #0x2e
xar v20.2d, v4.2d, v27.2d, #0x25
xar v4.2d, v24.2d, v27.2d, #0x32
xar v24.2d, v21.2d, v25.2d, #0x3e
xar v21.2d, v5.2d, v26.2d, #0x1c
xar v27.2d, v6.2d, v25.2d, #0x14
ld1r { v31.2d }, [x1], #8
bcax v5.16b, v10.16b, v7.16b, v11.16b
bcax v6.16b, v11.16b, v8.16b, v7.16b
bcax v7.16b, v7.16b, v9.16b, v8.16b
bcax v8.16b, v8.16b, v10.16b, v9.16b
bcax v9.16b, v9.16b, v11.16b, v10.16b
bcax v10.16b, v15.16b, v12.16b, v16.16b
bcax v11.16b, v16.16b, v13.16b, v12.16b
bcax v12.16b, v12.16b, v14.16b, v13.16b
bcax v13.16b, v13.16b, v15.16b, v14.16b
bcax v14.16b, v14.16b, v16.16b, v15.16b
bcax v15.16b, v20.16b, v17.16b, v21.16b
bcax v16.16b, v21.16b, v18.16b, v17.16b
bcax v17.16b, v17.16b, v19.16b, v18.16b
bcax v18.16b, v18.16b, v20.16b, v19.16b
bcax v19.16b, v19.16b, v21.16b, v20.16b
bcax v20.16b, v0.16b, v22.16b, v1.16b
bcax v21.16b, v1.16b, v23.16b, v22.16b
bcax v22.16b, v22.16b, v24.16b, v23.16b
bcax v23.16b, v23.16b, v0.16b, v24.16b
bcax v24.16b, v24.16b, v1.16b, v0.16b
bcax v0.16b, v30.16b, v2.16b, v27.16b
bcax v1.16b, v27.16b, v3.16b, v2.16b
bcax v2.16b, v2.16b, v4.16b, v3.16b
bcax v3.16b, v3.16b, v30.16b, v4.16b
bcax v4.16b, v4.16b, v27.16b, v30.16b
eor v0.16b, v0.16b, v31.16b
sub x2, x2, #0x1
cbnz x2, Lkeccak_f1600_x2_v84a_loop
sub x0, x0, #0xc0
add x2, x0, #0xc8
trn1 v25.2d, v0.2d, v1.2d
trn1 v26.2d, v2.2d, v3.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v0.2d, v1.2d
trn2 v28.2d, v2.2d, v3.2d
st1 { v27.2d, v28.2d }, [x2], #32
trn1 v25.2d, v4.2d, v5.2d
trn1 v26.2d, v6.2d, v7.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v4.2d, v5.2d
trn2 v28.2d, v6.2d, v7.2d
st1 { v27.2d, v28.2d }, [x2], #32
trn1 v25.2d, v8.2d, v9.2d
trn1 v26.2d, v10.2d, v11.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v8.2d, v9.2d
trn2 v28.2d, v10.2d, v11.2d
st1 { v27.2d, v28.2d }, [x2], #32
trn1 v25.2d, v12.2d, v13.2d
trn1 v26.2d, v14.2d, v15.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v12.2d, v13.2d
trn2 v28.2d, v14.2d, v15.2d
st1 { v27.2d, v28.2d }, [x2], #32
trn1 v25.2d, v16.2d, v17.2d
trn1 v26.2d, v18.2d, v19.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v16.2d, v17.2d
trn2 v28.2d, v18.2d, v19.2d
st1 { v27.2d, v28.2d }, [x2], #32
trn1 v25.2d, v20.2d, v21.2d
trn1 v26.2d, v22.2d, v23.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v20.2d, v21.2d
trn2 v28.2d, v22.2d, v23.2d
st1 { v27.2d, v28.2d }, [x2], #32
str d24, [x0]
trn2 v25.2d, v24.2d, v24.2d
str d25, [x2]
ldp d8, d9, [sp]
.cfi_restore d8
.cfi_restore d9
ldp d10, d11, [sp, #0x10]
.cfi_restore d10
.cfi_restore d11
ldp d12, d13, [sp, #0x20]
.cfi_restore d12
.cfi_restore d13
ldp d14, d15, [sp, #0x30]
.cfi_restore d14
.cfi_restore d15
add sp, sp, #0x40
.cfi_adjust_cfa_offset -0x40
ret
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x2_v84a_aarch64_asm)
#endif /* __ARM_FEATURE_SHA3 */
#endif /* MLK_FIPS202_AARCH64_NEED_X2_V84A && !MLK_CONFIG_MULTILEVEL_NO_SHARED \
*/
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,989 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) 2021-2022 Arm Limited
* Copyright (c) 2022 Matthias Kannwischer
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
// Author: Hanno Becker <hannobecker@posteo.de>
// Author: Matthias Kannwischer <matthias@kannwischer.eu>
/*yaml
Name: keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm
Description: AArch64 hybrid scalar/vector implementation of Keccak-f[1600] permutation for four sequential states with ARMv8.4-A optimizations
Signature: void mlk_keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm(uint64_t state[100], const uint64_t rc[24])
ABI:
Architecture: aarch64
CallingConvention: AAPCS64
Features: [SHA3]
x0:
type: buffer
size_bytes: 800
permissions: read/write
c_parameter: uint64_t state[100]
description: Four sequential Keccak states (state0[25], state1[25], state2[25], state3[25])
x1:
type: buffer
size_bytes: 192
permissions: read-only
c_parameter: const uint64_t rc[24]
description: Round constants (24 x uint64_t)
Stack:
bytes: 224
description: register preservation and temporary storage
*/
#include "../../../../common.h"
#if defined(MLK_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#if defined(__ARM_FEATURE_SHA3)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S using scripts/simpasm. Do not modify it directly.
*/
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm)
.cfi_startproc
sub sp, sp, #0xe0
.cfi_adjust_cfa_offset 0xe0
stp x19, x20, [sp, #0x30]
.cfi_rel_offset x19, 0x30
.cfi_rel_offset x20, 0x38
stp x21, x22, [sp, #0x40]
.cfi_rel_offset x21, 0x40
.cfi_rel_offset x22, 0x48
stp x23, x24, [sp, #0x50]
.cfi_rel_offset x23, 0x50
.cfi_rel_offset x24, 0x58
stp x25, x26, [sp, #0x60]
.cfi_rel_offset x25, 0x60
.cfi_rel_offset x26, 0x68
stp x27, x28, [sp, #0x70]
.cfi_rel_offset x27, 0x70
.cfi_rel_offset x28, 0x78
stp x29, x30, [sp, #0x80]
.cfi_rel_offset x29, 0x80
.cfi_rel_offset x30, 0x88
stp d8, d9, [sp, #0x90]
.cfi_rel_offset d8, 0x90
.cfi_rel_offset d9, 0x98
stp d10, d11, [sp, #0xa0]
.cfi_rel_offset d10, 0xa0
.cfi_rel_offset d11, 0xa8
stp d12, d13, [sp, #0xb0]
.cfi_rel_offset d12, 0xb0
.cfi_rel_offset d13, 0xb8
stp d14, d15, [sp, #0xc0]
.cfi_rel_offset d14, 0xc0
.cfi_rel_offset d15, 0xc8
mov x29, x1
mov x30, #0x0 // =0
str x30, [sp, #0x20]
str x29, [sp, #0x8]
str x29, [sp, #0x10]
str x0, [sp]
add x4, x0, #0xc8
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x4], #32
trn1 v0.2d, v25.2d, v27.2d
trn2 v1.2d, v25.2d, v27.2d
trn1 v2.2d, v26.2d, v28.2d
trn2 v3.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x4], #32
trn1 v4.2d, v25.2d, v27.2d
trn2 v5.2d, v25.2d, v27.2d
trn1 v6.2d, v26.2d, v28.2d
trn2 v7.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x4], #32
trn1 v8.2d, v25.2d, v27.2d
trn2 v9.2d, v25.2d, v27.2d
trn1 v10.2d, v26.2d, v28.2d
trn2 v11.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x4], #32
trn1 v12.2d, v25.2d, v27.2d
trn2 v13.2d, v25.2d, v27.2d
trn1 v14.2d, v26.2d, v28.2d
trn2 v15.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x4], #32
trn1 v16.2d, v25.2d, v27.2d
trn2 v17.2d, v25.2d, v27.2d
trn1 v18.2d, v26.2d, v28.2d
trn2 v19.2d, v26.2d, v28.2d
ldp q25, q26, [x0], #0x20
ld1 { v27.2d, v28.2d }, [x4], #32
trn1 v20.2d, v25.2d, v27.2d
trn2 v21.2d, v25.2d, v27.2d
trn1 v22.2d, v26.2d, v28.2d
trn2 v23.2d, v26.2d, v28.2d
ldr d25, [x0]
ldr d27, [x4]
trn1 v24.2d, v25.2d, v27.2d
sub x0, x0, #0xc0
add x0, x0, #0x190
ldp x1, x6, [x0]
ldp x11, x16, [x0, #0x10]
ldp x21, x2, [x0, #0x20]
ldp x7, x12, [x0, #0x30]
ldp x17, x22, [x0, #0x40]
ldp x3, x8, [x0, #0x50]
ldp x13, x28, [x0, #0x60]
ldp x23, x4, [x0, #0x70]
ldp x9, x14, [x0, #0x80]
ldp x19, x24, [x0, #0x90]
ldp x5, x10, [x0, #0xa0]
ldp x15, x20, [x0, #0xb0]
ldr x25, [x0, #0xc0]
sub x0, x0, #0x190
Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_initial:
eor x30, x24, x25
eor x27, x9, x10
eor3 v30.16b, v0.16b, v5.16b, v10.16b
eor v30.16b, v30.16b, v15.16b
eor x0, x30, x21
eor x26, x27, x6
eor v30.16b, v30.16b, v20.16b
eor x27, x26, x7
eor x29, x0, x22
eor3 v29.16b, v1.16b, v6.16b, v11.16b
eor x26, x29, x23
eor x29, x4, x5
eor v29.16b, v29.16b, v16.16b
eor x30, x29, x1
eor x0, x27, x8
eor v29.16b, v29.16b, v21.16b
eor x29, x30, x2
eor x30, x19, x20
eor3 v28.16b, v2.16b, v7.16b, v12.16b
eor x30, x30, x16
eor x27, x26, x0, ror #63
eor v28.16b, v28.16b, v17.16b
eor x4, x4, x27
eor x30, x30, x17
eor v28.16b, v28.16b, v22.16b
eor x30, x30, x28
eor x29, x29, x3
eor3 v27.16b, v3.16b, v8.16b, v13.16b
eor x0, x0, x30, ror #63
eor x30, x30, x29, ror #63
eor v27.16b, v27.16b, v18.16b
eor x22, x22, x30
eor v27.16b, v27.16b, v23.16b
eor x23, x23, x30
str x23, [sp, #0xd0]
eor3 v26.16b, v4.16b, v9.16b, v14.16b
eor x23, x14, x15
eor x14, x14, x0
eor v26.16b, v26.16b, v19.16b
eor x23, x23, x11
eor x15, x15, x0
eor v26.16b, v26.16b, v24.16b
eor x1, x1, x27
eor x23, x23, x12
rax1 v25.2d, v30.2d, v28.2d
eor x23, x23, x13
eor x11, x11, x0
add v31.2d, v26.2d, v26.2d
eor x29, x29, x23, ror #63
eor x23, x23, x26, ror #63
sri v31.2d, v26.2d, #0x3f
eor x26, x13, x0
eor x13, x28, x23
eor v28.16b, v31.16b, v28.16b
eor x28, x24, x30
eor x24, x16, x23
rax1 v26.2d, v26.2d, v29.2d
eor x16, x21, x30
eor x21, x25, x30
add v31.2d, v27.2d, v27.2d
eor x30, x19, x23
sri v31.2d, v27.2d, #0x3f
eor x19, x20, x23
eor x20, x17, x23
eor v29.16b, v31.16b, v29.16b
eor x17, x12, x0
eor x0, x2, x27
rax1 v27.2d, v27.2d, v30.2d
eor x2, x6, x29
eor x6, x8, x29
eor v30.16b, v0.16b, v26.16b
bic x8, x28, x13, ror #47
eor x12, x3, x27
eor v31.16b, v2.16b, v29.16b
bic x3, x13, x17, ror #19
eor x5, x5, x27
shl v0.2d, v31.2d, #0x3e
ldr x27, [sp, #0xd0]
bic x25, x17, x2, ror #5
sri v0.2d, v31.2d, #0x2
eor x9, x9, x29
eor x23, x25, x5, ror #52
xar v2.2d, v12.2d, v29.2d, #0x15
eor x3, x3, x2, ror #24
eor x8, x8, x17, ror #2
eor v31.16b, v13.16b, v28.16b
eor x17, x10, x29
bic x25, x12, x22, ror #47
shl v12.2d, v31.2d, #0x19
eor x29, x7, x29
bic x10, x4, x27, ror #2
sri v12.2d, v31.2d, #0x27
bic x7, x5, x28, ror #10
xar v13.2d, v19.2d, v27.2d, #0x38
eor x10, x10, x20, ror #50
eor x13, x7, x13, ror #57
eor v31.16b, v23.16b, v28.16b
bic x7, x2, x5, ror #47
eor x2, x25, x24, ror #39
shl v19.2d, v31.2d, #0x38
bic x25, x20, x11, ror #57
bic x5, x17, x4, ror #25
sri v19.2d, v31.2d, #0x8
eor x25, x25, x17, ror #53
bic x17, x11, x17, ror #60
xar v23.2d, v15.2d, v26.2d, #0x17
eor x28, x7, x28, ror #57
bic x7, x9, x12, ror #42
eor v31.16b, v1.16b, v25.16b
eor x7, x7, x22, ror #25
bic x22, x22, x24, ror #56
shl v15.2d, v31.2d, #0x1
bic x24, x24, x15, ror #31
eor x22, x22, x15, ror #23
sri v15.2d, v31.2d, #0x3f
bic x20, x27, x20, ror #48
bic x15, x15, x9, ror #16
xar v1.2d, v8.2d, v28.2d, #0x9
eor x12, x15, x12, ror #58
eor x15, x5, x27, ror #27
eor v31.16b, v16.16b, v25.16b
eor x5, x20, x11, ror #41
shl v8.2d, v31.2d, #0x2d
ldr x11, [sp, #0x8]
eor x20, x17, x4, ror #21
sri v8.2d, v31.2d, #0x13
eor x17, x24, x9, ror #47
mov x24, #0x1 // =1
xar v16.2d, v7.2d, v29.2d, #0x3a
bic x9, x0, x16, ror #9
str x24, [sp, #0x18]
eor v31.16b, v10.16b, v26.16b
bic x24, x29, x1, ror #44
bic x27, x1, x21, ror #50
shl v7.2d, v31.2d, #0x3
bic x4, x26, x29, ror #63
eor x1, x1, x4, ror #21
sri v7.2d, v31.2d, #0x3d
ldr x11, [x11]
bic x4, x21, x30, ror #57
xar v10.2d, v3.2d, v28.2d, #0x24
eor x21, x24, x21, ror #30
eor x24, x9, x19, ror #44
eor v31.16b, v18.16b, v28.16b
bic x9, x14, x6, ror #5
eor x9, x9, x0, ror #43
shl v3.2d, v31.2d, #0x15
bic x0, x6, x0, ror #38
eor x1, x1, x11
sri v3.2d, v31.2d, #0x2b
eor x11, x4, x26, ror #35
eor x4, x0, x16, ror #47
xar v18.2d, v17.2d, v29.2d, #0x31
bic x0, x16, x19, ror #35
eor v31.16b, v11.16b, v25.16b
eor x16, x27, x30, ror #43
bic x27, x30, x26, ror #42
shl v17.2d, v31.2d, #0xa
bic x26, x19, x14, ror #41
eor x19, x0, x14, ror #12
sri v17.2d, v31.2d, #0x36
eor x14, x26, x6, ror #46
eor x6, x27, x29, ror #41
xar v11.2d, v9.2d, v27.2d, #0x2c
eor x0, x15, x11, ror #52
eor x0, x0, x13, ror #48
eor v31.16b, v22.16b, v29.16b
eor x26, x8, x9, ror #57
eor x27, x0, x14, ror #10
shl v9.2d, v31.2d, #0x3d
eor x29, x16, x28, ror #63
eor x26, x26, x6, ror #51
sri v9.2d, v31.2d, #0x3
eor x30, x23, x22, ror #50
eor x0, x26, x10, ror #31
xar v22.2d, v14.2d, v27.2d, #0x19
eor x29, x29, x19, ror #37
eor x27, x27, x12, ror #5
eor v31.16b, v20.16b, v26.16b
eor x30, x30, x24, ror #34
eor x0, x0, x7, ror #27
shl v14.2d, v31.2d, #0x12
eor x26, x30, x21, ror #26
sri v14.2d, v31.2d, #0x2e
eor x26, x26, x25, ror #15
ror x30, x27, #0x3e
xar v20.2d, v4.2d, v27.2d, #0x25
eor x30, x30, x26, ror #57
ror x26, x26, #0x3a
eor v31.16b, v24.16b, v27.16b
eor x16, x30, x16
eor x28, x30, x28, ror #63
shl v4.2d, v31.2d, #0xe
str x28, [sp, #0xd0]
eor x29, x29, x17, ror #36
sri v4.2d, v31.2d, #0x32
eor x28, x1, x2, ror #61
eor x19, x30, x19, ror #37
xar v24.2d, v21.2d, v25.2d, #0x3e
eor x29, x29, x20, ror #2
eor x28, x28, x4, ror #54
eor v31.16b, v5.16b, v26.16b
eor x26, x26, x0, ror #55
eor x28, x28, x3, ror #39
shl v21.2d, v31.2d, #0x24
eor x28, x28, x5, ror #25
ror x0, x0, #0x38
sri v21.2d, v31.2d, #0x1c
eor x0, x0, x29, ror #63
eor x27, x28, x27, ror #61
xar v27.2d, v6.2d, v25.2d, #0x14
eor x13, x0, x13, ror #46
eor x28, x29, x28, ror #63
bic v31.16b, v7.16b, v11.16b
eor x29, x30, x20, ror #2
eor v5.16b, v31.16b, v10.16b
eor x20, x26, x3, ror #39
eor x11, x0, x11, ror #50
bcax v6.16b, v11.16b, v8.16b, v7.16b
eor x25, x28, x25, ror #9
eor x3, x28, x21, ror #20
bic v31.16b, v9.16b, v8.16b
eor x21, x26, x1
eor x9, x27, x9, ror #49
eor v7.16b, v31.16b, v7.16b
eor x24, x28, x24, ror #28
eor x1, x30, x17, ror #36
bcax v8.16b, v8.16b, v10.16b, v9.16b
eor x14, x0, x14, ror #8
eor x22, x28, x22, ror #44
bic v31.16b, v11.16b, v10.16b
eor x8, x27, x8, ror #56
eor x17, x27, x7, ror #19
eor v9.16b, v31.16b, v9.16b
eor x15, x0, x15, ror #62
bic x7, x20, x22, ror #47
bcax v10.16b, v15.16b, v12.16b, v16.16b
eor x4, x26, x4, ror #54
eor x0, x0, x12, ror #3
bic v31.16b, v13.16b, v12.16b
eor x28, x28, x23, ror #58
eor x23, x26, x2, ror #61
eor v11.16b, v31.16b, v16.16b
eor x26, x26, x5, ror #25
bcax v12.16b, v12.16b, v14.16b, v13.16b
eor x2, x7, x16, ror #39
bic x7, x9, x20, ror #42
bic v31.16b, v15.16b, v14.16b
bic x30, x15, x9, ror #16
eor x7, x7, x22, ror #25
eor v13.16b, v31.16b, v13.16b
eor x12, x30, x20, ror #58
bic x20, x22, x16, ror #56
bic v31.16b, v16.16b, v15.16b
eor x30, x27, x6, ror #43
eor x22, x20, x15, ror #23
eor v14.16b, v31.16b, v14.16b
bic x6, x19, x13, ror #42
eor x6, x6, x17, ror #41
bcax v15.16b, v20.16b, v17.16b, v21.16b
bic x5, x13, x17, ror #63
eor x5, x21, x5, ror #21
bic v31.16b, v18.16b, v17.16b
bic x17, x17, x21, ror #44
eor x27, x27, x10, ror #23
eor v16.16b, v31.16b, v21.16b
bic x21, x21, x25, ror #50
bic x20, x27, x4, ror #25
bcax v17.16b, v17.16b, v19.16b, v18.16b
bic x10, x16, x15, ror #31
eor x16, x21, x19, ror #43
bic v31.16b, v20.16b, v19.16b
eor x21, x17, x25, ror #30
bic x19, x25, x19, ror #57
eor v18.16b, v31.16b, v18.16b
ldr x25, [sp, #0x18]
bcax v19.16b, v19.16b, v21.16b, v20.16b
eor x17, x10, x9, ror #47
ldr x9, [sp, #0x8]
bic v31.16b, v22.16b, v1.16b
eor x15, x20, x28, ror #27
bic x20, x4, x28, ror #2
eor v20.16b, v31.16b, v0.16b
eor x10, x20, x1, ror #50
bic x20, x11, x27, ror #60
bcax v21.16b, v1.16b, v23.16b, v22.16b
eor x20, x20, x4, ror #21
bic x4, x28, x1, ror #48
bic v31.16b, v24.16b, v23.16b
bic x1, x1, x11, ror #57
ldr x28, [x9, x25, lsl #3]
eor v22.16b, v31.16b, v22.16b
ldr x9, [sp, #0xd0]
add x25, x25, #0x1
bcax v23.16b, v23.16b, v0.16b, v24.16b
str x25, [sp, #0x18]
cmp x25, #0x17
bic v31.16b, v1.16b, v0.16b
eor x25, x1, x27, ror #53
bic x27, x30, x26, ror #47
eor v24.16b, v31.16b, v24.16b
eor x1, x5, x28
eor x5, x4, x11, ror #41
bcax v0.16b, v30.16b, v2.16b, v27.16b
eor x11, x19, x13, ror #35
bic v31.16b, v3.16b, v2.16b
bic x13, x26, x24, ror #10
eor x28, x27, x24, ror #57
eor v1.16b, v31.16b, v27.16b
bic x27, x24, x9, ror #47
bic x19, x23, x3, ror #9
bcax v2.16b, v2.16b, v4.16b, v3.16b
bic x4, x29, x14, ror #41
eor x24, x19, x29, ror #44
bic v31.16b, v30.16b, v4.16b
bic x29, x3, x29, ror #35
eor x13, x13, x9, ror #57
eor v3.16b, v31.16b, v3.16b
eor x19, x29, x14, ror #12
bic x29, x9, x0, ror #19
bcax v4.16b, v4.16b, v27.16b, v30.16b
bic x14, x14, x8, ror #5
eor x9, x14, x23, ror #43
eor x14, x4, x8, ror #46
bic x23, x8, x23, ror #38
eor x8, x27, x0, ror #2
eor x4, x23, x3, ror #47
bic x3, x0, x30, ror #5
eor x23, x3, x26, ror #52
eor x3, x29, x30, ror #24
ldr x30, [sp, #0x10]
ld1r { v28.2d }, [x30], #8
str x30, [sp, #0x10]
eor v0.16b, v0.16b, v28.16b
Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_loop:
eor x0, x15, x11, ror #52
eor x0, x0, x13, ror #48
eor3 v30.16b, v0.16b, v5.16b, v10.16b
eor v30.16b, v30.16b, v15.16b
eor x26, x8, x9, ror #57
eor x27, x0, x14, ror #10
eor v30.16b, v30.16b, v20.16b
eor x29, x16, x28, ror #63
eor x26, x26, x6, ror #51
eor3 v29.16b, v1.16b, v6.16b, v11.16b
eor x30, x23, x22, ror #50
eor x0, x26, x10, ror #31
eor v29.16b, v29.16b, v16.16b
eor x29, x29, x19, ror #37
eor x27, x27, x12, ror #5
eor v29.16b, v29.16b, v21.16b
eor x30, x30, x24, ror #34
eor x0, x0, x7, ror #27
eor3 v28.16b, v2.16b, v7.16b, v12.16b
eor x26, x30, x21, ror #26
eor x26, x26, x25, ror #15
eor v28.16b, v28.16b, v17.16b
ror x30, x27, #0x3e
eor x30, x30, x26, ror #57
eor v28.16b, v28.16b, v22.16b
ror x26, x26, #0x3a
eor x16, x30, x16
eor3 v27.16b, v3.16b, v8.16b, v13.16b
eor x28, x30, x28, ror #63
str x28, [sp, #0xd0]
eor v27.16b, v27.16b, v18.16b
eor x29, x29, x17, ror #36
eor x28, x1, x2, ror #61
eor v27.16b, v27.16b, v23.16b
eor x19, x30, x19, ror #37
eor x29, x29, x20, ror #2
eor3 v26.16b, v4.16b, v9.16b, v14.16b
eor x28, x28, x4, ror #54
eor x26, x26, x0, ror #55
eor v26.16b, v26.16b, v19.16b
eor x28, x28, x3, ror #39
eor x28, x28, x5, ror #25
eor v26.16b, v26.16b, v24.16b
ror x0, x0, #0x38
eor x0, x0, x29, ror #63
rax1 v25.2d, v30.2d, v28.2d
eor x27, x28, x27, ror #61
eor x13, x0, x13, ror #46
add v31.2d, v26.2d, v26.2d
eor x28, x29, x28, ror #63
eor x29, x30, x20, ror #2
sri v31.2d, v26.2d, #0x3f
eor x20, x26, x3, ror #39
eor x11, x0, x11, ror #50
eor v28.16b, v31.16b, v28.16b
eor x25, x28, x25, ror #9
eor x3, x28, x21, ror #20
rax1 v26.2d, v26.2d, v29.2d
eor x21, x26, x1
add v31.2d, v27.2d, v27.2d
eor x9, x27, x9, ror #49
eor x24, x28, x24, ror #28
sri v31.2d, v27.2d, #0x3f
eor x1, x30, x17, ror #36
eor x14, x0, x14, ror #8
eor v29.16b, v31.16b, v29.16b
eor x22, x28, x22, ror #44
eor x8, x27, x8, ror #56
rax1 v27.2d, v27.2d, v30.2d
eor x17, x27, x7, ror #19
eor x15, x0, x15, ror #62
eor v30.16b, v0.16b, v26.16b
bic x7, x20, x22, ror #47
eor x4, x26, x4, ror #54
eor v31.16b, v2.16b, v29.16b
eor x0, x0, x12, ror #3
eor x28, x28, x23, ror #58
shl v0.2d, v31.2d, #0x3e
eor x23, x26, x2, ror #61
eor x26, x26, x5, ror #25
sri v0.2d, v31.2d, #0x2
eor x2, x7, x16, ror #39
bic x7, x9, x20, ror #42
xar v2.2d, v12.2d, v29.2d, #0x15
bic x30, x15, x9, ror #16
eor x7, x7, x22, ror #25
eor v31.16b, v13.16b, v28.16b
eor x12, x30, x20, ror #58
bic x20, x22, x16, ror #56
shl v12.2d, v31.2d, #0x19
eor x30, x27, x6, ror #43
eor x22, x20, x15, ror #23
sri v12.2d, v31.2d, #0x27
bic x6, x19, x13, ror #42
eor x6, x6, x17, ror #41
xar v13.2d, v19.2d, v27.2d, #0x38
bic x5, x13, x17, ror #63
eor x5, x21, x5, ror #21
eor v31.16b, v23.16b, v28.16b
bic x17, x17, x21, ror #44
eor x27, x27, x10, ror #23
shl v19.2d, v31.2d, #0x38
bic x21, x21, x25, ror #50
bic x20, x27, x4, ror #25
sri v19.2d, v31.2d, #0x8
bic x10, x16, x15, ror #31
eor x16, x21, x19, ror #43
xar v23.2d, v15.2d, v26.2d, #0x17
eor x21, x17, x25, ror #30
bic x19, x25, x19, ror #57
eor v31.16b, v1.16b, v25.16b
ldr x25, [sp, #0x18]
eor x17, x10, x9, ror #47
shl v15.2d, v31.2d, #0x1
ldr x9, [sp, #0x8]
sri v15.2d, v31.2d, #0x3f
eor x15, x20, x28, ror #27
bic x20, x4, x28, ror #2
xar v1.2d, v8.2d, v28.2d, #0x9
eor x10, x20, x1, ror #50
bic x20, x11, x27, ror #60
eor v31.16b, v16.16b, v25.16b
eor x20, x20, x4, ror #21
bic x4, x28, x1, ror #48
shl v8.2d, v31.2d, #0x2d
bic x1, x1, x11, ror #57
ldr x28, [x9, x25, lsl #3]
sri v8.2d, v31.2d, #0x13
ldr x9, [sp, #0xd0]
add x25, x25, #0x1
xar v16.2d, v7.2d, v29.2d, #0x3a
str x25, [sp, #0x18]
cmp x25, #0x17
eor v31.16b, v10.16b, v26.16b
eor x25, x1, x27, ror #53
bic x27, x30, x26, ror #47
shl v7.2d, v31.2d, #0x3
eor x1, x5, x28
eor x5, x4, x11, ror #41
sri v7.2d, v31.2d, #0x3d
eor x11, x19, x13, ror #35
bic x13, x26, x24, ror #10
xar v10.2d, v3.2d, v28.2d, #0x24
eor x28, x27, x24, ror #57
bic x27, x24, x9, ror #47
eor v31.16b, v18.16b, v28.16b
bic x19, x23, x3, ror #9
bic x4, x29, x14, ror #41
shl v3.2d, v31.2d, #0x15
eor x24, x19, x29, ror #44
bic x29, x3, x29, ror #35
sri v3.2d, v31.2d, #0x2b
eor x13, x13, x9, ror #57
eor x19, x29, x14, ror #12
xar v18.2d, v17.2d, v29.2d, #0x31
bic x29, x9, x0, ror #19
bic x14, x14, x8, ror #5
eor v31.16b, v11.16b, v25.16b
eor x9, x14, x23, ror #43
eor x14, x4, x8, ror #46
shl v17.2d, v31.2d, #0xa
bic x23, x8, x23, ror #38
eor x8, x27, x0, ror #2
sri v17.2d, v31.2d, #0x36
eor x4, x23, x3, ror #47
bic x3, x0, x30, ror #5
xar v11.2d, v9.2d, v27.2d, #0x2c
eor x23, x3, x26, ror #52
eor x3, x29, x30, ror #24
eor v31.16b, v22.16b, v29.16b
eor x0, x15, x11, ror #52
shl v9.2d, v31.2d, #0x3d
eor x0, x0, x13, ror #48
eor x26, x8, x9, ror #57
sri v9.2d, v31.2d, #0x3
eor x27, x0, x14, ror #10
eor x29, x16, x28, ror #63
xar v22.2d, v14.2d, v27.2d, #0x19
eor x26, x26, x6, ror #51
eor x30, x23, x22, ror #50
eor v31.16b, v20.16b, v26.16b
eor x0, x26, x10, ror #31
eor x29, x29, x19, ror #37
shl v14.2d, v31.2d, #0x12
eor x27, x27, x12, ror #5
eor x30, x30, x24, ror #34
sri v14.2d, v31.2d, #0x2e
eor x0, x0, x7, ror #27
eor x26, x30, x21, ror #26
xar v20.2d, v4.2d, v27.2d, #0x25
eor x26, x26, x25, ror #15
ror x30, x27, #0x3e
eor v31.16b, v24.16b, v27.16b
eor x30, x30, x26, ror #57
ror x26, x26, #0x3a
shl v4.2d, v31.2d, #0xe
eor x16, x30, x16
eor x28, x30, x28, ror #63
sri v4.2d, v31.2d, #0x32
str x28, [sp, #0xd0]
eor x29, x29, x17, ror #36
xar v24.2d, v21.2d, v25.2d, #0x3e
eor x28, x1, x2, ror #61
eor x19, x30, x19, ror #37
eor v31.16b, v5.16b, v26.16b
eor x29, x29, x20, ror #2
eor x28, x28, x4, ror #54
shl v21.2d, v31.2d, #0x24
eor x26, x26, x0, ror #55
eor x28, x28, x3, ror #39
sri v21.2d, v31.2d, #0x1c
eor x28, x28, x5, ror #25
ror x0, x0, #0x38
xar v27.2d, v6.2d, v25.2d, #0x14
eor x0, x0, x29, ror #63
eor x27, x28, x27, ror #61
bic v31.16b, v7.16b, v11.16b
eor x13, x0, x13, ror #46
eor x28, x29, x28, ror #63
eor v5.16b, v31.16b, v10.16b
eor x29, x30, x20, ror #2
eor x20, x26, x3, ror #39
bcax v6.16b, v11.16b, v8.16b, v7.16b
eor x11, x0, x11, ror #50
eor x25, x28, x25, ror #9
bic v31.16b, v9.16b, v8.16b
eor x3, x28, x21, ror #20
eor v7.16b, v31.16b, v7.16b
eor x21, x26, x1
eor x9, x27, x9, ror #49
bcax v8.16b, v8.16b, v10.16b, v9.16b
eor x24, x28, x24, ror #28
eor x1, x30, x17, ror #36
bic v31.16b, v11.16b, v10.16b
eor x14, x0, x14, ror #8
eor x22, x28, x22, ror #44
eor v9.16b, v31.16b, v9.16b
eor x8, x27, x8, ror #56
eor x17, x27, x7, ror #19
bcax v10.16b, v15.16b, v12.16b, v16.16b
eor x15, x0, x15, ror #62
bic x7, x20, x22, ror #47
bic v31.16b, v13.16b, v12.16b
eor x4, x26, x4, ror #54
eor x0, x0, x12, ror #3
eor v11.16b, v31.16b, v16.16b
eor x28, x28, x23, ror #58
eor x23, x26, x2, ror #61
bcax v12.16b, v12.16b, v14.16b, v13.16b
eor x26, x26, x5, ror #25
eor x2, x7, x16, ror #39
bic v31.16b, v15.16b, v14.16b
bic x7, x9, x20, ror #42
bic x30, x15, x9, ror #16
eor v13.16b, v31.16b, v13.16b
eor x7, x7, x22, ror #25
eor x12, x30, x20, ror #58
bic v31.16b, v16.16b, v15.16b
bic x20, x22, x16, ror #56
eor x30, x27, x6, ror #43
eor v14.16b, v31.16b, v14.16b
eor x22, x20, x15, ror #23
bic x6, x19, x13, ror #42
bcax v15.16b, v20.16b, v17.16b, v21.16b
eor x6, x6, x17, ror #41
bic x5, x13, x17, ror #63
bic v31.16b, v18.16b, v17.16b
eor x5, x21, x5, ror #21
bic x17, x17, x21, ror #44
eor v16.16b, v31.16b, v21.16b
eor x27, x27, x10, ror #23
bic x21, x21, x25, ror #50
bcax v17.16b, v17.16b, v19.16b, v18.16b
bic x20, x27, x4, ror #25
bic x10, x16, x15, ror #31
bic v31.16b, v20.16b, v19.16b
eor x16, x21, x19, ror #43
eor x21, x17, x25, ror #30
eor v18.16b, v31.16b, v18.16b
bic x19, x25, x19, ror #57
ldr x25, [sp, #0x18]
bcax v19.16b, v19.16b, v21.16b, v20.16b
eor x17, x10, x9, ror #47
bic v31.16b, v22.16b, v1.16b
ldr x9, [sp, #0x8]
eor x15, x20, x28, ror #27
eor v20.16b, v31.16b, v0.16b
bic x20, x4, x28, ror #2
eor x10, x20, x1, ror #50
bcax v21.16b, v1.16b, v23.16b, v22.16b
bic x20, x11, x27, ror #60
eor x20, x20, x4, ror #21
bic v31.16b, v24.16b, v23.16b
bic x4, x28, x1, ror #48
bic x1, x1, x11, ror #57
eor v22.16b, v31.16b, v22.16b
ldr x28, [x9, x25, lsl #3]
ldr x9, [sp, #0xd0]
bcax v23.16b, v23.16b, v0.16b, v24.16b
add x25, x25, #0x1
str x25, [sp, #0x18]
bic v31.16b, v1.16b, v0.16b
cmp x25, #0x17
eor x25, x1, x27, ror #53
eor v24.16b, v31.16b, v24.16b
bic x27, x30, x26, ror #47
eor x1, x5, x28
bcax v0.16b, v30.16b, v2.16b, v27.16b
eor x5, x4, x11, ror #41
eor x11, x19, x13, ror #35
bic v31.16b, v3.16b, v2.16b
bic x13, x26, x24, ror #10
eor x28, x27, x24, ror #57
eor v1.16b, v31.16b, v27.16b
bic x27, x24, x9, ror #47
bic x19, x23, x3, ror #9
bcax v2.16b, v2.16b, v4.16b, v3.16b
bic x4, x29, x14, ror #41
eor x24, x19, x29, ror #44
bic v31.16b, v30.16b, v4.16b
bic x29, x3, x29, ror #35
eor x13, x13, x9, ror #57
eor v3.16b, v31.16b, v3.16b
eor x19, x29, x14, ror #12
bic x29, x9, x0, ror #19
bcax v4.16b, v4.16b, v27.16b, v30.16b
bic x14, x14, x8, ror #5
eor x9, x14, x23, ror #43
eor x14, x4, x8, ror #46
bic x23, x8, x23, ror #38
eor x8, x27, x0, ror #2
eor x4, x23, x3, ror #47
bic x3, x0, x30, ror #5
eor x23, x3, x26, ror #52
eor x3, x29, x30, ror #24
ldr x30, [sp, #0x10]
ld1r { v28.2d }, [x30], #8
str x30, [sp, #0x10]
eor v0.16b, v0.16b, v28.16b
Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_loop_end:
b.le Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_loop
ror x2, x2, #0x3d
ror x3, x3, #0x27
ror x4, x4, #0x36
ror x5, x5, #0x19
ror x6, x6, #0x2b
ror x7, x7, #0x13
ror x8, x8, #0x38
ror x9, x9, #0x31
ror x10, x10, #0x17
ror x11, x11, #0x32
ror x12, x12, #0x3
ror x13, x13, #0x2e
ror x14, x14, #0x8
ror x15, x15, #0x3e
ror x17, x17, #0x24
ror x28, x28, #0x3f
ror x19, x19, #0x25
ror x20, x20, #0x2
ror x21, x21, #0x14
ror x22, x22, #0x2c
ror x23, x23, #0x3a
ror x24, x24, #0x1c
ror x25, x25, #0x9
ldr x30, [sp, #0x20]
cmp x30, #0x1
b.eq Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_done
mov x30, #0x1 // =1
str x30, [sp, #0x20]
ldr x0, [sp]
add x0, x0, #0x190
stp x1, x6, [x0]
stp x11, x16, [x0, #0x10]
stp x21, x2, [x0, #0x20]
stp x7, x12, [x0, #0x30]
stp x17, x22, [x0, #0x40]
stp x3, x8, [x0, #0x50]
stp x13, x28, [x0, #0x60]
stp x23, x4, [x0, #0x70]
stp x9, x14, [x0, #0x80]
stp x19, x24, [x0, #0x90]
stp x5, x10, [x0, #0xa0]
stp x15, x20, [x0, #0xb0]
str x25, [x0, #0xc0]
sub x0, x0, #0x190
add x0, x0, #0x258
ldp x1, x6, [x0]
ldp x11, x16, [x0, #0x10]
ldp x21, x2, [x0, #0x20]
ldp x7, x12, [x0, #0x30]
ldp x17, x22, [x0, #0x40]
ldp x3, x8, [x0, #0x50]
ldp x13, x28, [x0, #0x60]
ldp x23, x4, [x0, #0x70]
ldp x9, x14, [x0, #0x80]
ldp x19, x24, [x0, #0x90]
ldp x5, x10, [x0, #0xa0]
ldp x15, x20, [x0, #0xb0]
ldr x25, [x0, #0xc0]
sub x0, x0, #0x258
b Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_initial
Lkeccak_f1600_x4_v8a_v84a_scalar_hybrid_done:
ldr x0, [sp]
add x0, x0, #0x258
stp x1, x6, [x0]
stp x11, x16, [x0, #0x10]
stp x21, x2, [x0, #0x20]
stp x7, x12, [x0, #0x30]
stp x17, x22, [x0, #0x40]
stp x3, x8, [x0, #0x50]
stp x13, x28, [x0, #0x60]
stp x23, x4, [x0, #0x70]
stp x9, x14, [x0, #0x80]
stp x19, x24, [x0, #0x90]
stp x5, x10, [x0, #0xa0]
stp x15, x20, [x0, #0xb0]
str x25, [x0, #0xc0]
sub x0, x0, #0x258
add x4, x0, #0xc8
trn1 v25.2d, v0.2d, v1.2d
trn1 v26.2d, v2.2d, v3.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v0.2d, v1.2d
trn2 v28.2d, v2.2d, v3.2d
st1 { v27.2d, v28.2d }, [x4], #32
trn1 v25.2d, v4.2d, v5.2d
trn1 v26.2d, v6.2d, v7.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v4.2d, v5.2d
trn2 v28.2d, v6.2d, v7.2d
st1 { v27.2d, v28.2d }, [x4], #32
trn1 v25.2d, v8.2d, v9.2d
trn1 v26.2d, v10.2d, v11.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v8.2d, v9.2d
trn2 v28.2d, v10.2d, v11.2d
st1 { v27.2d, v28.2d }, [x4], #32
trn1 v25.2d, v12.2d, v13.2d
trn1 v26.2d, v14.2d, v15.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v12.2d, v13.2d
trn2 v28.2d, v14.2d, v15.2d
st1 { v27.2d, v28.2d }, [x4], #32
trn1 v25.2d, v16.2d, v17.2d
trn1 v26.2d, v18.2d, v19.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v16.2d, v17.2d
trn2 v28.2d, v18.2d, v19.2d
st1 { v27.2d, v28.2d }, [x4], #32
trn1 v25.2d, v20.2d, v21.2d
trn1 v26.2d, v22.2d, v23.2d
stp q25, q26, [x0], #0x20
trn2 v27.2d, v20.2d, v21.2d
trn2 v28.2d, v22.2d, v23.2d
st1 { v27.2d, v28.2d }, [x4], #32
str d24, [x0]
trn2 v25.2d, v24.2d, v24.2d
str d25, [x4]
ldp d8, d9, [sp, #0x90]
.cfi_restore d8
.cfi_restore d9
ldp d10, d11, [sp, #0xa0]
.cfi_restore d10
.cfi_restore d11
ldp d12, d13, [sp, #0xb0]
.cfi_restore d12
.cfi_restore d13
ldp d14, d15, [sp, #0xc0]
.cfi_restore d14
.cfi_restore d15
ldp x19, x20, [sp, #0x30]
.cfi_restore x19
.cfi_restore x20
ldp x21, x22, [sp, #0x40]
.cfi_restore x21
.cfi_restore x22
ldp x23, x24, [sp, #0x50]
.cfi_restore x23
.cfi_restore x24
ldp x25, x26, [sp, #0x60]
.cfi_restore x25
.cfi_restore x26
ldp x27, x28, [sp, #0x70]
.cfi_restore x27
.cfi_restore x28
ldp x29, x30, [sp, #0x80]
.cfi_restore x29
.cfi_restore x30
add sp, sp, #0xe0
.cfi_adjust_cfa_offset -0xe0
ret
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm)
#endif /* __ARM_FEATURE_SHA3 */
#endif /* MLK_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID && \
!MLK_CONFIG_MULTILEVEL_NO_SHARED */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/*
* WARNING: This file is auto-generated from scripts/autogen
* in the mlkem-native repository.
* Do not modify it directly.
*/
#include "../../../../common.h"
#if (defined(MLK_FIPS202_AARCH64_NEED_X1_SCALAR) || \
defined(MLK_FIPS202_AARCH64_NEED_X1_V84A) || \
defined(MLK_FIPS202_AARCH64_NEED_X2_V84A) || \
defined(MLK_FIPS202_AARCH64_NEED_X4_V8A_SCALAR_HYBRID) || \
defined(MLK_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID)) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#include "fips202_native_aarch64.h"
MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const uint64_t
mlk_keccakf1600_round_constants[24] = {
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
};
#else /* (MLK_FIPS202_AARCH64_NEED_X1_SCALAR || \
MLK_FIPS202_AARCH64_NEED_X1_V84A || MLK_FIPS202_AARCH64_NEED_X2_V84A \
|| MLK_FIPS202_AARCH64_NEED_X4_V8A_SCALAR_HYBRID || \
MLK_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID) && \
!MLK_CONFIG_MULTILEVEL_NO_SHARED */
MLK_EMPTY_CU(fips202_aarch64_round_constants)
#endif /* !((MLK_FIPS202_AARCH64_NEED_X1_SCALAR || \
MLK_FIPS202_AARCH64_NEED_X1_V84A || MLK_FIPS202_AARCH64_NEED_X2_V84A \
|| MLK_FIPS202_AARCH64_NEED_X4_V8A_SCALAR_HYBRID || \
MLK_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID) && \
!MLK_CONFIG_MULTILEVEL_NO_SHARED) */

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_X1_SCALAR_H
#define MLK_FIPS202_NATIVE_AARCH64_X1_SCALAR_H
/* Part of backend API */
#define MLK_USE_FIPS202_X1_NATIVE
/* Guard for assembly file */
#define MLK_FIPS202_AARCH64_NEED_X1_SCALAR
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_aarch64.h"
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x1_native(uint64_t *state)
{
mlk_keccak_f1600_x1_scalar_aarch64_asm(state,
mlk_keccakf1600_round_constants);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_AARCH64_X1_SCALAR_H */

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_X1_V84A_H
#define MLK_FIPS202_NATIVE_AARCH64_X1_V84A_H
#if !defined(__ARM_FEATURE_SHA3)
#error This backend can only be used if SHA3 extensions are available.
#endif
/* Part of backend API */
#define MLK_USE_FIPS202_X1_NATIVE
/* Guard for assembly file */
#define MLK_FIPS202_AARCH64_NEED_X1_V84A
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_aarch64.h"
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x1_native(uint64_t *state)
{
if (!mlk_sys_check_capability(MLK_SYS_CAP_SHA3))
{
return MLK_NATIVE_FUNC_FALLBACK;
}
mlk_keccak_f1600_x1_v84a_aarch64_asm(state, mlk_keccakf1600_round_constants);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_AARCH64_X1_V84A_H */

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_X2_V84A_H
#define MLK_FIPS202_NATIVE_AARCH64_X2_V84A_H
#if !defined(__ARM_FEATURE_SHA3)
#error This backend can only be used if SHA3 extensions are available.
#endif
/* Part of backend API */
#define MLK_USE_FIPS202_X4_NATIVE
/* Guard for assembly file */
#define MLK_FIPS202_AARCH64_NEED_X2_V84A
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_aarch64.h"
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x4_native(uint64_t *state)
{
if (!mlk_sys_check_capability(MLK_SYS_CAP_SHA3))
{
return MLK_NATIVE_FUNC_FALLBACK;
}
mlk_keccak_f1600_x2_v84a_aarch64_asm(state + 0 * 25,
mlk_keccakf1600_round_constants);
mlk_keccak_f1600_x2_v84a_aarch64_asm(state + 2 * 25,
mlk_keccakf1600_round_constants);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_AARCH64_X2_V84A_H */

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_X4_V8A_SCALAR_H
#define MLK_FIPS202_NATIVE_AARCH64_X4_V8A_SCALAR_H
/* Part of backend API */
#define MLK_USE_FIPS202_X4_NATIVE
/* Guard for assembly file */
#define MLK_FIPS202_AARCH64_NEED_X4_V8A_SCALAR_HYBRID
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_aarch64.h"
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x4_native(uint64_t *state)
{
mlk_keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm(
state, mlk_keccakf1600_round_constants);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_AARCH64_X4_V8A_SCALAR_H */

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AARCH64_X4_V8A_V84A_SCALAR_H
#define MLK_FIPS202_NATIVE_AARCH64_X4_V8A_V84A_SCALAR_H
#if !defined(__ARM_FEATURE_SHA3)
#error This backend can only be used if SHA3 extensions are available.
#endif
/* Part of backend API */
#define MLK_USE_FIPS202_X4_NATIVE
/* Guard for assembly file */
#define MLK_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_aarch64.h"
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x4_native(uint64_t *state)
{
if (!mlk_sys_check_capability(MLK_SYS_CAP_SHA3))
{
return MLK_NATIVE_FUNC_FALLBACK;
}
mlk_keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm(
state, mlk_keccakf1600_round_constants);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_AARCH64_X4_V8A_V84A_SCALAR_H */

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_API_H
#define MLK_FIPS202_NATIVE_API_H
/*
* FIPS-202 native interface
*
* This header is primarily for documentation purposes.
* It should not be included by backend implementations.
*/
#include "../../cbmc.h"
/* Backends must return MLK_NATIVE_FUNC_SUCCESS upon success. */
#define MLK_NATIVE_FUNC_SUCCESS (0)
/* Backends may return MLK_NATIVE_FUNC_FALLBACK to signal to the frontend that
* the target/parameters are unsupported; typically, this would be because of
* dependencies on CPU features not detected on the host CPU. In this case,
* the frontend falls back to the default C implementation. */
#define MLK_NATIVE_FUNC_FALLBACK (-1)
/*
* This is the C<->native interface allowing for the drop-in
* of custom Keccak-F1600 implementations.
*
* A _backend_ is a specific implementation of parts of this interface.
*
* You can replace 1-fold or 4-fold batched Keccak-F1600.
* To enable, set MLK_USE_FIPS202_X1_NATIVE or MLK_USE_FIPS202_X4_NATIVE
* in your backend, and define the inline wrappers mlk_keccak_f1600_x1_native()
* and/or mlk_keccak_f1600_x4_native(), respectively, to forward to your
* implementation.
*/
#if defined(MLK_USE_FIPS202_X1_NATIVE)
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x1_native(uint64_t *state)
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 1))
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 1))
ensures(return_value == MLK_NATIVE_FUNC_FALLBACK || return_value == MLK_NATIVE_FUNC_SUCCESS)
ensures((return_value == MLK_NATIVE_FUNC_FALLBACK) ==> array_unchanged_u64(state, 25 * 1)));
#endif /* MLK_USE_FIPS202_X1_NATIVE */
#if defined(MLK_USE_FIPS202_X4_NATIVE)
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x4_native(uint64_t *state)
__contract__(
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 4))
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 4))
ensures(return_value == MLK_NATIVE_FUNC_FALLBACK || return_value == MLK_NATIVE_FUNC_SUCCESS)
ensures((return_value == MLK_NATIVE_FUNC_FALLBACK) ==> array_unchanged_u64(state, 25 * 4)));
#endif /* MLK_USE_FIPS202_X4_NATIVE */
/*
* Native x4 XOR bytes and extract bytes interface.
*
* These functions allow backends to provide optimized implementations for
* XORing input data into the state and extracting output data from the state.
* This is particularly useful for backends that use a different internal state
* representation (e.g., bit-interleaved), as conversion can happen during
* XOR/extract rather than before/after each permutation.
*
* NOTE: We assume that the custom representation of the zero state is the
* all-zero state.
*
* MLK_USE_FIPS202_X4_XOR_BYTES_NATIVE: Backend provides native XOR bytes
* MLK_USE_FIPS202_X4_EXTRACT_BYTES_NATIVE: Backend provides native extract
* bytes
*/
#if defined(MLK_USE_FIPS202_X4_XOR_BYTES_NATIVE)
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccakf1600_xor_bytes_x4_native(
uint64_t *state, const unsigned char *data0, const unsigned char *data1,
const unsigned char *data2, const unsigned char *data3, unsigned offset,
unsigned length)
__contract__(
requires(0 <= offset && offset <= 25 * sizeof(uint64_t) &&
0 <= length && length <= 25 * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 4))
requires(memory_no_alias(data0, length))
requires((data0 == data1 &&
data0 == data2 &&
data0 == data3) ||
(memory_no_alias(data1, length) &&
memory_no_alias(data2, length) &&
memory_no_alias(data3, length)))
assigns(memory_slice(state, sizeof(uint64_t) * 25 * 4))
ensures(return_value == MLK_NATIVE_FUNC_FALLBACK || return_value == MLK_NATIVE_FUNC_SUCCESS)
ensures((return_value == MLK_NATIVE_FUNC_FALLBACK) ==> array_unchanged_u64(state, 25 * 4)));
#endif /* MLK_USE_FIPS202_X4_XOR_BYTES_NATIVE */
#if defined(MLK_USE_FIPS202_X4_EXTRACT_BYTES_NATIVE)
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccakf1600_extract_bytes_x4_native(
uint64_t *state, unsigned char *data0, unsigned char *data1,
unsigned char *data2, unsigned char *data3, unsigned offset,
unsigned length)
__contract__(
requires(0 <= offset && offset <= 25 * sizeof(uint64_t) &&
0 <= length && length <= 25 * sizeof(uint64_t) - offset)
requires(memory_no_alias(state, sizeof(uint64_t) * 25 * 4))
requires(memory_no_alias(data0, length))
requires(memory_no_alias(data1, length))
requires(memory_no_alias(data2, length))
requires(memory_no_alias(data3, length))
assigns(memory_slice(data0, length))
assigns(memory_slice(data1, length))
assigns(memory_slice(data2, length))
assigns(memory_slice(data3, length))
ensures(return_value == MLK_NATIVE_FUNC_FALLBACK || return_value == MLK_NATIVE_FUNC_SUCCESS));
#endif /* MLK_USE_FIPS202_X4_EXTRACT_BYTES_NATIVE */
#endif /* !MLK_FIPS202_NATIVE_API_H */

View File

@@ -0,0 +1,10 @@
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
# FIPS202 backend for Armv8.1-M + MVE
This directory contains the source code for a FIPS202 backend targeting
the Armv8.1-M + MVE/Helium architecture. It is automatically derived from
the respective development source in [dev/fips202/armv81m](../../../../../dev/fips202/armv81m).
**Warning:** This backend is still in active development and has not yet undergone
the same level of review as the rest of the code. Use at your own risk!

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_ARMV81M_MVE_H
#define MLK_FIPS202_NATIVE_ARMV81M_MVE_H
#define MLK_FIPS202_NATIVE_ARMV81M
/* Part of backend API */
#define MLK_USE_FIPS202_X4_NATIVE
#define MLK_USE_FIPS202_X4_XOR_BYTES_NATIVE
#define MLK_USE_FIPS202_X4_EXTRACT_BYTES_NATIVE
/* Guard for assembly file */
#define MLK_FIPS202_ARMV81M_NEED_X4
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_armv81m.h"
/*
* Native x4 permutation
* State is kept in bit-interleaved format.
*/
#define mlk_keccak_f1600_x4_native_impl \
MLK_NAMESPACE(keccak_f1600_x4_native_impl)
int mlk_keccak_f1600_x4_native_impl(uint64_t *state);
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x4_native(uint64_t *state)
{
return mlk_keccak_f1600_x4_native_impl(state);
}
/*
* Native x4 XOR bytes (with on-the-fly bit interleaving)
*/
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccakf1600_xor_bytes_x4_native(
uint64_t *state, const uint8_t *data0, const uint8_t *data1,
const uint8_t *data2, const uint8_t *data3, unsigned offset,
unsigned length)
{
mlk_keccak_f1600_x4_state_xor_bytes_asm(state, data0, data1, data2, data3,
offset, length);
return MLK_NATIVE_FUNC_SUCCESS;
}
/*
* Native x4 extract bytes (with on-the-fly bit de-interleaving)
*/
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccakf1600_extract_bytes_x4_native(
uint64_t *state, uint8_t *data0, uint8_t *data1, uint8_t *data2,
uint8_t *data3, unsigned offset, unsigned length)
{
mlk_keccak_f1600_x4_state_extract_bytes_asm(state, data0, data1, data2, data3,
offset, length);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_ARMV81M_MVE_H */

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_ARMV81M_SRC_FIPS202_NATIVE_ARMV81M_H
#define MLK_FIPS202_NATIVE_ARMV81M_SRC_FIPS202_NATIVE_ARMV81M_H
#include "../../../../common.h"
/* Keccak round constants in bit-interleaved form */
#define mlk_keccakf1600_round_constants \
MLK_NAMESPACE(keccakf1600_round_constants)
MLK_INTERNAL_DATA_DECLARATION const uint32_t
mlk_keccakf1600_round_constants[48];
#define mlk_keccak_f1600_x4_mve_asm MLK_NAMESPACE(keccak_f1600_x4_mve_asm)
void mlk_keccak_f1600_x4_mve_asm(uint64_t state[100], uint64_t tmpstate[100],
const uint32_t rc[48]);
#define mlk_keccak_f1600_x4_state_xor_bytes_asm \
MLK_NAMESPACE(keccak_f1600_x4_state_xor_bytes_asm)
void mlk_keccak_f1600_x4_state_xor_bytes_asm(void *state, const uint8_t *d0,
const uint8_t *d1,
const uint8_t *d2,
const uint8_t *d3, unsigned offset,
unsigned length);
#define mlk_keccak_f1600_x4_state_extract_bytes_asm \
MLK_NAMESPACE(keccak_f1600_x4_state_extract_bytes_asm)
void mlk_keccak_f1600_x4_state_extract_bytes_asm(void *state, uint8_t *data0,
uint8_t *data1, uint8_t *data2,
uint8_t *data3,
unsigned offset,
unsigned length);
#endif /* !MLK_FIPS202_NATIVE_ARMV81M_SRC_FIPS202_NATIVE_ARMV81M_H */

View File

@@ -0,0 +1,716 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) 2025 Arm Limited
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/*yaml
Name: keccak_f1600_x4_mve_asm
Description: Armv8.1-M MVE implementation of batched (x4) Keccak-f[1600] permutation using bit-interleaved state
Signature: void mlk_keccak_f1600_x4_mve_asm(void *state, void *tmpstate, const uint32_t *rc)
ABI:
Architecture: armv81m
CallingConvention: AAPCS32
Features: [MVE]
r0:
type: buffer
size_bytes: 800
permissions: read/write
c_parameter: void *state
description: Bit-interleaved state for 4 Keccak instances (even halves followed by odd halves)
r1:
type: buffer
size_bytes: 800
permissions: read/write
c_parameter: void *tmpstate
description: Temporary storage for intermediate state
r2:
type: buffer
size_bytes: 192
permissions: read
c_parameter: const uint32_t *rc
description: Keccak round constants in bit-interleaved form (24 pairs of 32-bit words)
Stack:
bytes: 228
description: register preservation (36) + SIMD registers (64) + temporary storage (128)
*/
// ---------------------------------------------------------------------------
// Bit-interleaving background
// ---------------------------------------------------------------------------
// Each 64-bit Keccak lane is stored as two 32-bit words:
// even half -- bits 0, 2, 4, ..., 62 of the lane
// odd half -- bits 1, 3, 5, ..., 63 of the lane
// This representation allows 64-bit lane rotations (used in the Keccak
// round function) to be implemented as pairs of 32-bit rotations.
//
// Batched (x4) processing:
// Four Keccak instances are processed as a batch. Their states are
// stored interleaved in a single 800-byte buffer: first the even
// halves of all 25 lanes (400 bytes), then the odd halves (400 bytes).
// Within each 16-byte row, the four u32 words correspond to
// instances 0..3 of the same lane, enabling SIMD-parallel operations
// across all four instances.
//
// State memory layout (25 lanes x 4 instances x 2 halves):
// S[i][l]_even/odd = even/odd half of lane l, instance i (u32)
// Each row is 16 bytes (one Q-register).
// Offset Contents
// 0 S[0][ 0]_even, S[1][ 0]_even, S[2][ 0]_even, S[3][ 0]_even
// 16 S[0][ 1]_even, S[1][ 1]_even, S[2][ 1]_even, S[3][ 1]_even
// ...
// 384 S[0][24]_even, S[1][24]_even, S[2][24]_even, S[3][24]_even
// 400 S[0][ 0]_odd, S[1][ 0]_odd, S[2][ 0]_odd, S[3][ 0]_odd
// 416 S[0][ 1]_odd, S[1][ 1]_odd, S[2][ 1]_odd, S[3][ 1]_odd
// ...
// 784 S[0][24]_odd, S[1][24]_odd, S[2][24]_odd, S[3][24]_odd
#include "../../../../common.h"
#if defined(MLK_FIPS202_ARMV81M_NEED_X4) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/armv81m/src/keccak_f1600_x4_mve.S using scripts/simpasm. Do not modify it directly.
*/
.thumb
.syntax unified
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x4_mve_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x4_mve_asm)
.cfi_startproc
push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}
.cfi_adjust_cfa_offset 0x24
.cfi_rel_offset r4, 0x0
.cfi_rel_offset r5, 0x4
.cfi_rel_offset r6, 0x8
.cfi_rel_offset r7, 0xc
.cfi_rel_offset r8, 0x10
.cfi_rel_offset r9, 0x14
.cfi_rel_offset r10, 0x18
.cfi_rel_offset r11, 0x1c
.cfi_rel_offset lr, 0x20
vpush {d8, d9, d10, d11, d12, d13, d14, d15}
.cfi_adjust_cfa_offset 0x40
.cfi_rel_offset d8, 0x0
.cfi_rel_offset d9, 0x8
.cfi_rel_offset d10, 0x10
.cfi_rel_offset d11, 0x18
.cfi_rel_offset d12, 0x20
.cfi_rel_offset d13, 0x28
.cfi_rel_offset d14, 0x30
.cfi_rel_offset d15, 0x38
sub sp, #0x80
.cfi_adjust_cfa_offset 0x80
mov r6, r2
mov.w lr, #0x18
mov r2, r0
mov r4, r1
add.w r3, r2, #0x190
vldrw.u32 q0, [r3]
vldrw.u32 q1, [r2]
vldrw.u32 q2, [r2, #32]
wls lr, lr, Lkeccak_f1600_x4_mve_asm_roundend @ imm = #0x8c0
Lkeccak_f1600_x4_mve_asm_roundstart:
vldrw.u32 q6, [r2, #112]
veor q7, q6, q2
vldrw.u32 q2, [r2, #80]
veor q1, q2, q1
add.w r5, r2, #0x190
vldrw.u32 q5, [r5, #80]
veor q4, q5, q0
vldrw.u32 q0, [r2, #192]
veor q3, q7, q0
vldrw.u32 q0, [r2, #160]
veor q1, q1, q0
vldrw.u32 q0, [r5, #160]
veor q0, q4, q0
vldrw.u32 q6, [r2, #272]
veor q2, q3, q6
vldrw.u32 q7, [r2, #240]
veor q5, q1, q7
vldrw.u32 q4, [r5, #240]
veor q4, q0, q4
vldrw.u32 q6, [r2, #352]
veor q3, q2, q6
vldrw.u32 q0, [r2, #320]
veor q2, q5, q0
vldrw.u32 q1, [r5, #320]
veor q5, q4, q1
vldrw.u32 q4, [r5, #32]
veor q0, q3, q5
vldrw.u32 q1, [r5, #16]
veor q6, q1, q0
vstrw.32 q5, [sp]
vshr.u32 q7, q6, #0x1f
add.w r10, r4, #0x190
vsli.32 q7, q6, #0x1
vldrw.u32 q6, [r5, #112]
veor q6, q4, q6
vldrw.u32 q4, [r5, #192]
veor q4, q6, q4
vldrw.u32 q6, [r5, #272]
veor q4, q4, q6
vldrw.u32 q6, [r5, #352]
veor q5, q4, q6
vstrw.32 q7, [r4, #160]
vshr.u32 q4, q5, #0x1f
vsli.32 q4, q5, #0x1
vldrw.u32 q6, [r2, #16]
veor q7, q4, q2
veor q1, q6, q7
vldrw.u32 q6, [r5, #96]
veor q6, q6, q0
vstrw.32 q1, [r10, #160]
vshr.u32 q1, q6, #0xa
vsli.32 q1, q6, #0x16
vldrw.u32 q6, [r2, #96]
veor q4, q6, q7
vstrw.32 q1, [r10, #16]
vshr.u32 q6, q4, #0xa
vsli.32 q6, q4, #0x16
vldrw.u32 q1, [r5, #336]
veor q4, q1, q0
vldrw.u32 q1, [r2, #176]
veor q1, q1, q7
vstrw.32 q6, [r4, #16]
vshr.u32 q6, q1, #0x1b
vsli.32 q6, q1, #0x5
vldrw.u32 q1, [r2, #256]
veor q1, q1, q7
vstrw.32 q6, [r4, #272]
vshr.u32 q6, q1, #0xa
vsli.32 q6, q1, #0x16
vldrw.u32 q1, [r2, #336]
veor q1, q1, q7
vstrw.32 q6, [r10, #128]
vshr.u32 q6, q1, #0x1f
vsli.32 q6, q1, #0x1
vldrw.u32 q7, [r5, #176]
veor q7, q7, q0
vstrw.32 q6, [r4, #384]
vshr.u32 q1, q7, #0x1b
vsli.32 q1, q7, #0x5
vldrw.u32 q6, [r5, #256]
veor q0, q6, q0
vstrw.32 q1, [r10, #272]
vshr.u32 q1, q4, #0x1f
vldrw.u32 q7, [r5, #64]
vsli.32 q1, q4, #0x1
vldrw.u32 q4, [r5, #144]
vshr.u32 q6, q0, #0x9
vstrw.32 q1, [r10, #384]
vsli.32 q6, q0, #0x17
veor q7, q7, q4
vldrw.u32 q1, [r5, #224]
veor q4, q7, q1
vldrw.u32 q7, [r5, #304]
veor q1, q4, q7
vldrw.u32 q0, [r5, #384]
veor q7, q1, q0
vstrw.32 q6, [r4, #128]
vshr.u32 q1, q7, #0x1f
vsli.32 q1, q7, #0x1
vldrw.u32 q6, [r2, #144]
veor q0, q1, q3
vldrw.u32 q3, [r2, #64]
veor q1, q3, q6
vldrw.u32 q6, [r2, #224]
veor q1, q1, q6
vldrw.u32 q3, [r2, #304]
veor q6, q1, q3
vldrw.u32 q4, [r2, #384]
veor q3, q6, q4
vldrw.u32 q4, [r2, #48]
veor q5, q3, q5
vldrw.u32 q1, [r5, #48]
veor q1, q1, q5
vshr.u32 q6, q1, #0x12
vsli.32 q6, q1, #0xe
vldrw.u32 q1, [r2, #128]
veor q1, q1, q0
vstrw.32 q6, [r10, #80]
vshr.u32 q6, q1, #0x5
vsli.32 q6, q1, #0x1b
vldrw.u32 q1, [r5, #128]
veor q1, q1, q5
vstrw.32 q6, [r10, #336]
vshr.u32 q6, q1, #0x4
vsli.32 q6, q1, #0x1c
veor q1, q4, q0
vstrw.32 q6, [r4, #336]
vshr.u32 q4, q1, #0x12
vsli.32 q4, q1, #0xe
vldrw.u32 q6, [r2, #208]
veor q6, q6, q0
vstrw.32 q4, [r4, #80]
vshr.u32 q1, q6, #0x14
vsli.32 q1, q6, #0xc
vldrw.u32 q4, [r2, #288]
veor q4, q4, q0
vldrw.u32 q6, [r2, #368]
veor q0, q6, q0
vshr.u32 q6, q0, #0x4
vstrw.32 q1, [r10, #192]
vsli.32 q6, q0, #0x1c
vshr.u32 q0, q4, #0x16
vldrw.u32 q1, [r5, #368]
vsli.32 q0, q4, #0xa
vstrw.32 q6, [r4, #304]
veor q4, q1, q5
vstrw.32 q0, [r10, #48]
vshr.u32 q1, q4, #0x4
vsli.32 q1, q4, #0x1c
vldrw.u32 q6, [r5, #208]
veor q6, q6, q5
vldrw.u32 q0, [r5, #288]
veor q5, q0, q5
vstrw.32 q1, [r10, #304]
vshr.u32 q0, q6, #0x13
vsli.32 q0, q6, #0xd
vldrw.u32 q1, [r5, #96]
vshr.u32 q6, q5, #0x15
vldrw.u32 q4, [r5, #16]
vsli.32 q6, q5, #0xb
vldrw.u32 q5, [r5, #176]
veor q1, q4, q1
vldrw.u32 q4, [r5, #256]
veor q5, q1, q5
vldrw.u32 q1, [r5, #336]
veor q5, q5, q4
vstrw.32 q0, [r4, #192]
veor q0, q5, q1
vstrw.32 q6, [r4, #48]
vshr.u32 q5, q0, #0x1f
vsli.32 q5, q0, #0x1
vldrw.u32 q4, [r2, #16]
veor q3, q5, q3
vldrw.u32 q6, [r2, #96]
veor q4, q4, q6
vldrw.u32 q1, [r2, #176]
veor q5, q4, q1
vldrw.u32 q6, [r2, #256]
veor q6, q5, q6
vldrw.u32 q4, [r2, #336]
veor q5, q6, q4
vldrw.u32 q1, [r5]
veor q7, q5, q7
vldrw.u32 q4, [r2]
veor q1, q1, q7
veor q4, q4, q3
vshr.u32 q6, q1, #0x20
vsli.32 q6, q1, #0x0
vldrw.u32 q1, [r2, #80]
veor q1, q1, q3
vstrw.32 q6, [r10]
vshr.u32 q6, q4, #0x20
vsli.32 q6, q4, #0x0
vldrw.u32 q4, [r5, #80]
veor q4, q4, q7
vstrw.32 q6, [r4]
vshr.u32 q6, q1, #0xe
vsli.32 q6, q1, #0x12
vldrw.u32 q1, [r2, #160]
veor q1, q1, q3
vstrw.32 q6, [r4, #256]
vshr.u32 q6, q4, #0xe
vsli.32 q6, q4, #0x12
vldrw.u32 q4, [r2, #240]
veor q4, q4, q3
vstrw.32 q6, [r10, #256]
vshr.u32 q6, q1, #0x1f
vsli.32 q6, q1, #0x1
vldrw.u32 q1, [r2, #320]
veor q1, q1, q3
vstrw.32 q6, [r10, #112]
vshr.u32 q6, q4, #0xc
vsli.32 q6, q4, #0x14
vldrw.u32 q3, [r5, #240]
veor q3, q3, q7
vstrw.32 q6, [r10, #368]
vshr.u32 q4, q3, #0xb
vsli.32 q4, q3, #0x15
vldrw.u32 q3, [r5, #160]
veor q6, q3, q7
vstrw.32 q4, [r4, #368]
vshr.u32 q3, q6, #0x1e
vsli.32 q3, q6, #0x2
vldrw.u32 q6, [r5, #320]
veor q7, q6, q7
vldrw.u32 q4, [r2, #368]
vshr.u32 q6, q1, #0x17
vstrw.32 q3, [r4, #112]
vsli.32 q6, q1, #0x9
vshr.u32 q1, q7, #0x17
vldrw.u32 q3, [r2, #48]
vsli.32 q1, q7, #0x9
vldrw.u32 q7, [r2, #128]
veor q3, q3, q7
vldrw.u32 q7, [r2, #208]
veor q7, q3, q7
vldrw.u32 q3, [r2, #288]
veor q3, q7, q3
vldrw.u32 q7, [r5, #128]
veor q3, q3, q4
vldrw.u32 q4, [r5, #48]
veor q0, q3, q0
veor q4, q4, q7
vldrw.u32 q7, [r5, #208]
veor q4, q4, q7
vldrw.u32 q7, [r5, #288]
veor q4, q4, q7
vldrw.u32 q7, [r5, #368]
veor q7, q4, q7
vstrw.32 q6, [r4, #224]
vshr.u32 q4, q7, #0x1f
vstrw.32 q1, [r10, #224]
vsli.32 q4, q7, #0x1
veor q5, q4, q5
vldrw.u32 q6, [r2, #192]
veor q1, q6, q5
vldrw.u32 q4, [r5, #112]
veor q7, q2, q7
vldrw.u32 q6, [r5, #32]
vshr.u32 q2, q1, #0xb
vsli.32 q2, q1, #0x15
veor q1, q6, q0
vstrw.32 q2, [r10, #32]
vshr.u32 q6, q1, #0x1
vsli.32 q6, q1, #0x1f
vldrw.u32 q2, [r2, #112]
veor q2, q2, q5
vstrw.32 q6, [r10, #320]
vshr.u32 q1, q2, #0x1d
vsli.32 q1, q2, #0x3
vldrw.u32 q6, [r2, #32]
veor q4, q4, q0
vstrw.32 q1, [r4, #176]
veor q2, q6, q5
vshr.u32 q6, q2, #0x1
vldrw.u32 q1, [r5, #352]
vsli.32 q6, q2, #0x1f
veor q1, q1, q0
vstrw.32 q6, [r4, #320]
vshr.u32 q6, q1, #0x1
vsli.32 q6, q1, #0x1f
vldrw.u32 q2, [r5, #192]
vshr.u32 q1, q4, #0x1d
vstrw.32 q6, [r4, #144]
vsli.32 q1, q4, #0x3
veor q2, q2, q0
vldrw.u32 q6, [r5, #272]
veor q0, q6, q0
vldrw.u32 q4, [r2, #352]
veor q6, q4, q5
vldrw.u32 q4, [r2, #272]
veor q4, q4, q5
vstrw.32 q1, [r10, #176]
vshr.u32 q1, q2, #0xa
vsli.32 q1, q2, #0x16
vldrw.u32 q5, [sp]
vshr.u32 q2, q0, #0x18
vstrw.32 q1, [r4, #32]
vsli.32 q2, q0, #0x8
vshr.u32 q1, q6, #0x2
vstrw.32 q2, [r4, #288]
vsli.32 q1, q6, #0x1e
vshr.u32 q6, q4, #0x19
vstrw.32 q1, [r10, #144]
vsli.32 q6, q4, #0x7
vshr.u32 q0, q5, #0x1f
vstrw.32 q6, [r10, #288]
vsli.32 q0, q5, #0x1
veor q5, q0, q3
vldrw.u32 q6, [r2, #64]
veor q3, q6, q5
vldrw.u32 q1, [r5, #64]
vshr.u32 q4, q3, #0x13
vldrw.u32 q2, [r2, #384]
vsli.32 q4, q3, #0xd
vldrw.u32 q0, [r5, #224]
veor q6, q1, q7
vstrw.32 q4, [r10, #240]
veor q2, q2, q5
veor q3, q0, q7
vldrw.u32 q0, [r2, #224]
vshr.u32 q4, q6, #0x12
vldrw.u32 q1, [r5, #384]
vsli.32 q4, q6, #0xe
vshr.u32 q6, q2, #0x19
vstrw.32 q4, [r4, #240]
vsli.32 q6, q2, #0x7
vshr.u32 q2, q3, #0xc
vstrw.32 q6, [r4, #64]
vsli.32 q2, q3, #0x14
veor q0, q0, q5
vldrw.u32 q6, [r2, #144]
veor q4, q1, q7
veor q6, q6, q5
vstrw.32 q2, [r4, #352]
vshr.u32 q2, q4, #0x19
vsli.32 q2, q4, #0x7
vldrw.u32 q1, [r2, #304]
veor q5, q1, q5
vldrw.u32 q1, [r5, #144]
veor q4, q1, q7
vldrw.u32 q3, [r5, #304]
veor q1, q3, q7
vstrw.32 q2, [r10, #64]
vshr.u32 q3, q0, #0xd
vsli.32 q3, q0, #0x13
vldrw.u32 q7, [r4, #80]
vshr.u32 q0, q6, #0x16
vstrw.32 q3, [r10, #352]
vsli.32 q0, q6, #0xa
vshr.u32 q2, q5, #0x1c
vsli.32 q2, q5, #0x4
vldrw.u32 q5, [r4, #112]
vshr.u32 q3, q1, #0x1c
vsli.32 q3, q1, #0x4
vldrw.u32 q1, [r4, #128]
vbic q6, q5, q0
vstrw.32 q3, [r10, #208]
vbic q3, q1, q5
veor q3, q0, q3
vstrw.32 q3, [r2, #96]
vbic q3, q0, q7
veor q0, q7, q6
vldrw.u32 q6, [r4, #144]
vbic q7, q7, q6
vstrw.32 q0, [r2, #80]
veor q3, q6, q3
vstrw.32 q3, [r2, #144]
veor q0, q1, q7
vstrw.32 q0, [r2, #128]
vbic q1, q6, q1
vshr.u32 q6, q4, #0x16
vldrw.u32 q3, [r10, #112]
vsli.32 q6, q4, #0xa
vldrw.u32 q4, [r10, #80]
veor q1, q5, q1
vldrw.u32 q0, [r10, #144]
vbic q7, q4, q0
vldrw.u32 q5, [r10, #128]
veor q7, q5, q7
vstrw.32 q1, [r2, #112]
vbic q1, q0, q5
vstrw.32 q7, [r5, #128]
veor q7, q3, q1
vstrw.32 q7, [r5, #112]
vbic q7, q5, q3
vbic q1, q3, q6
vldrw.u32 q3, [r4, #176]
veor q5, q4, q1
vbic q4, q6, q4
vldrw.u32 q1, [r4, #160]
veor q0, q0, q4
vldrw.u32 q4, [r4, #224]
veor q7, q6, q7
vstrw.32 q0, [r5, #144]
vbic q0, q1, q4
vstrw.32 q7, [r5, #96]
veor q0, q2, q0
vstrw.32 q0, [r2, #208]
vbic q6, q3, q1
vstrw.32 q5, [r5, #80]
vbic q7, q4, q2
vldrw.u32 q0, [r10, #160]
veor q6, q4, q6
vldrw.u32 q5, [r4, #192]
vbic q4, q2, q5
vldrw.u32 q2, [r10, #224]
veor q4, q3, q4
vstrw.32 q4, [r2, #176]
vbic q4, q5, q3
vstrw.32 q6, [r2, #224]
veor q4, q1, q4
vldrw.u32 q1, [r10, #208]
veor q3, q5, q7
vldrw.u32 q5, [r10, #192]
vbic q6, q1, q5
vldrw.u32 q7, [r10, #176]
veor q6, q7, q6
vstrw.32 q3, [r2, #192]
vbic q3, q0, q2
vstrw.32 q6, [r5, #176]
veor q3, q1, q3
vstrw.32 q3, [r5, #208]
vbic q3, q5, q7
vstrw.32 q4, [r2, #160]
veor q3, q0, q3
vstrw.32 q3, [r5, #160]
vbic q6, q2, q1
vldrw.u32 q1, [r4, #288]
vbic q7, q7, q0
vldrw.u32 q3, [r4, #272]
veor q0, q5, q6
vldrw.u32 q4, [r4, #304]
veor q6, q2, q7
vldrw.u32 q7, [r4, #256]
vbic q5, q4, q1
vstrw.32 q0, [r5, #192]
veor q5, q3, q5
vstrw.32 q6, [r5, #224]
vbic q0, q3, q7
vstrw.32 q5, [r2, #272]
vbic q6, q1, q3
veor q5, q7, q6
vldrw.u32 q3, [r4, #240]
veor q6, q3, q0
vldrw.u32 q2, [r10, #288]
vbic q0, q3, q4
vstrw.32 q6, [r2, #240]
vbic q7, q7, q3
vstrw.32 q5, [r2, #256]
veor q7, q4, q7
vstrw.32 q7, [r2, #304]
veor q7, q1, q0
vstrw.32 q7, [r2, #288]
vldrw.u32 q5, [r10, #304]
vbic q7, q5, q2
vldrw.u32 q3, [r10, #272]
veor q1, q3, q7
vldrw.u32 q7, [r4, #336]
vbic q4, q2, q3
vldrw.u32 q6, [r10, #256]
vbic q3, q3, q6
vldrw.u32 q0, [r10, #240]
veor q3, q0, q3
vstrw.32 q1, [r5, #272]
vbic q1, q0, q5
vstrw.32 q3, [r5, #240]
veor q1, q2, q1
vldrw.u32 q3, [r4, #384]
vbic q2, q6, q0
vldrw.u32 q0, [r4, #320]
veor q2, q5, q2
vldrw.u32 q5, [r4, #352]
veor q4, q6, q4
vstrw.32 q2, [r5, #304]
vbic q2, q7, q0
vstrw.32 q1, [r5, #288]
veor q1, q3, q2
vstrw.32 q1, [r2, #384]
vbic q2, q5, q7
vstrw.32 q4, [r5, #256]
veor q4, q0, q2
vstrw.32 q4, [r2, #320]
vbic q2, q0, q3
vldrw.u32 q4, [r4, #368]
vbic q3, q3, q4
vldrw.u32 q0, [r10, #320]
veor q1, q5, q3
vldrw.u32 q6, [r10, #336]
vbic q5, q4, q5
vstrw.32 q1, [r2, #352]
veor q5, q7, q5
vstrw.32 q5, [r2, #336]
veor q3, q4, q2
vstrw.32 q3, [r2, #368]
vbic q7, q6, q0
vldrw.u32 q5, [r10, #352]
vbic q3, q5, q6
vldrw.u32 q1, [r10, #368]
vbic q4, q1, q5
vldrw.u32 q2, [r4, #16]
veor q6, q6, q4
vldrw.u32 q4, [r10, #384]
veor q3, q0, q3
vstrw.32 q3, [r5, #320]
veor q3, q4, q7
vstrw.32 q3, [r5, #384]
vbic q0, q0, q4
vstrw.32 q6, [r5, #336]
veor q3, q1, q0
vstrw.32 q3, [r5, #368]
vbic q7, q4, q1
veor q5, q5, q7
vldrw.u32 q6, [r4, #32]
vbic q3, q6, q2
vldrw.u32 q4, [r4, #48]
vbic q0, q4, q6
vldrw.u32 q1, [r4]
veor q0, q2, q0
vldrw.u32 q7, [r4, #64]
veor q3, q1, q3
vstrw.32 q5, [r5, #352]
vbic q5, q1, q7
vstrw.32 q0, [r2, #16]
veor q0, q4, q5
vstrw.32 q0, [r2, #48]
vbic q5, q2, q1
veor q2, q7, q5
vldrw.u32 q0, [r10, #16]
vbic q5, q7, q4
vldrw.u32 q4, [r10]
vbic q1, q0, q4
vldrw.u32 q7, [r10, #64]
veor q1, q7, q1
vstrw.32 q2, [r2, #64]
veor q2, q6, q5
vbic q6, q4, q7
vldrw.u32 q5, [r10, #48]
veor q6, q5, q6
ldrd r7, r8, [r6]
vbic q7, q7, q5
vstrw.32 q1, [r5, #64]
vdup.32 q1, r7
veor q1, q3, q1
vldrw.u32 q3, [r10, #32]
veor q7, q3, q7
add.w r6, r6, #0x8
vbic q5, q5, q3
vstrw.32 q6, [r5, #48]
vbic q6, q3, q0
vstrw.32 q1, [r2]
veor q5, q0, q5
vstrw.32 q7, [r5, #32]
veor q4, q4, q6
vstrw.32 q5, [r5, #16]
vdup.32 q6, r8
vstrw.32 q2, [r2, #32]
veor q0, q4, q6
vstrw.32 q0, [r5]
Lkeccak_f1600_x4_mve_asm_roundend_pre:
le lr, Lkeccak_f1600_x4_mve_asm_roundstart @ imm = #-0x8c0
Lkeccak_f1600_x4_mve_asm_roundend:
add sp, #0x80
.cfi_adjust_cfa_offset -0x80
vpop {d8, d9, d10, d11, d12, d13, d14, d15}
.cfi_restore d8
.cfi_restore d9
.cfi_restore d10
.cfi_restore d11
.cfi_restore d12
.cfi_restore d13
.cfi_restore d14
.cfi_restore d15
.cfi_adjust_cfa_offset -0x40
pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.cfi_restore r4
.cfi_restore r5
.cfi_restore r6
.cfi_restore r7
.cfi_restore r8
.cfi_restore r9
.cfi_restore r10
.cfi_restore r11
.cfi_restore lr
.cfi_adjust_cfa_offset -0x24
.cfi_endproc
nop
MLK_ASM_FN_SIZE(keccak_f1600_x4_mve_asm)
#endif /* MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#include "../../../../common.h"
#include "../../../../verify.h"
#if defined(MLK_FIPS202_ARMV81M_NEED_X4) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#include "fips202_native_armv81m.h"
/*
* Keccak-f1600 x4 permutation (on bit-interleaved state)
* State is expected to already be in bit-interleaved format.
*/
#define mlk_keccak_f1600_x4_native_impl \
MLK_NAMESPACE(keccak_f1600_x4_native_impl)
int mlk_keccak_f1600_x4_native_impl(uint64_t *state)
{
MLK_ALIGN uint64_t state_tmp[100];
mlk_keccak_f1600_x4_mve_asm(state, state_tmp,
mlk_keccakf1600_round_constants);
mlk_zeroize(state_tmp, sizeof(state_tmp));
return MLK_NATIVE_FUNC_SUCCESS;
}
#else /* MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED */
MLK_EMPTY_CU(keccak_f1600_x4_mve)
#endif /* !(MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED) \
*/
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
* Don't modify by hand -- this is auto-generated by scripts/autogen. */
/* Some macros are kept because they are also defined in a header. */
/* Keep: mlk_keccak_f1600_x4_native_impl (mve.h) */

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#include "../../../../common.h"
#if defined(MLK_FIPS202_ARMV81M_NEED_X4) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#include "fips202_native_armv81m.h"
/*
* Keccak round constants in bit-interleaved form.
* Each 64-bit constant is split into two 32-bit words:
* - low word contains even-indexed bits
* - high word contains odd-indexed bits
*/
MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const uint32_t
mlk_keccakf1600_round_constants[48] = {
0x00000001, 0x00000000, /* RC0 */
0x00000000, 0x00000089, /* RC1 */
0x00000000, 0x8000008b, /* RC2 */
0x00000000, 0x80008080, /* RC3 */
0x00000001, 0x0000008b, /* RC4 */
0x00000001, 0x00008000, /* RC5 */
0x00000001, 0x80008088, /* RC6 */
0x00000001, 0x80000082, /* RC7 */
0x00000000, 0x0000000b, /* RC8 */
0x00000000, 0x0000000a, /* RC9 */
0x00000001, 0x00008082, /* RC10 */
0x00000000, 0x00008003, /* RC11 */
0x00000001, 0x0000808b, /* RC12 */
0x00000001, 0x8000000b, /* RC13 */
0x00000001, 0x8000008a, /* RC14 */
0x00000001, 0x80000081, /* RC15 */
0x00000000, 0x80000081, /* RC16 */
0x00000000, 0x80000008, /* RC17 */
0x00000000, 0x00000083, /* RC18 */
0x00000000, 0x80008003, /* RC19 */
0x00000001, 0x80008088, /* RC20 */
0x00000000, 0x80000088, /* RC21 */
0x00000001, 0x00008000, /* RC22 */
0x00000000, 0x80008082, /* RC23 */
};
#else /* MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED */
MLK_EMPTY_CU(fips202_armv81m_round_constants)
#endif /* !(MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED) \
*/

View File

@@ -0,0 +1,334 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) The mldsa-native project authors
* Copyright (c) 2026 Arm Limited
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
// ---------------------------------------------------------------------------
// Overview
// ---------------------------------------------------------------------------
// MVE/Helium implementation of KeccakF1600x4_StateExtractBytes
// (inverse of state_xor_bytes_x4_mve.S).
//
// void KeccakF1600x4_StateExtractBytes(state, d0, d1, d2, d3, offset, length)
//
// Reads 'length' bytes from the bit-interleaved Keccak state starting at
// byte 'offset', recombines the even and odd halves of each lane back
// into plain bytes, and writes them to four output buffers (d0..d3).
//
// ---------------------------------------------------------------------------
// Bit-interleaving background
// ---------------------------------------------------------------------------
// Each 64-bit Keccak lane is stored as two 32-bit words:
// even half -- bits 0, 2, 4, ..., 62 of the lane
// odd half -- bits 1, 3, 5, ..., 63 of the lane
// This representation allows 64-bit lane rotations (used in the Keccak
// round function) to be implemented as pairs of 32-bit rotations.
//
// Batched (x4) processing:
// Four Keccak instances are processed as a batch. Their states are
// stored interleaved in a single 800-byte buffer: first the even
// halves of all 25 lanes (400 bytes), then the odd halves (400 bytes).
// Within each 16-byte row, the four u32 words correspond to
// instances 0..3 of the same lane, enabling SIMD-parallel operations
// across all four instances.
//
// State memory layout (25 lanes x 4 instances x 2 halves):
// S[i][l]_even/odd = even/odd half of lane l, instance i (u32)
// Each row is 16 bytes (one Q-register).
// Offset Contents
// 0 S[0][ 0]_even, S[1][ 0]_even, S[2][ 0]_even, S[3][ 0]_even
// 16 S[0][ 1]_even, S[1][ 1]_even, S[2][ 1]_even, S[3][ 1]_even
// ...
// 384 S[0][24]_even, S[1][24]_even, S[2][24]_even, S[3][24]_even
// 400 S[0][ 0]_odd, S[1][ 0]_odd, S[2][ 0]_odd, S[3][ 0]_odd
// 416 S[0][ 1]_odd, S[1][ 1]_odd, S[2][ 1]_odd, S[3][ 1]_odd
// ...
// 784 S[0][24]_odd, S[1][24]_odd, S[2][24]_odd, S[3][24]_odd
//
// ---------------------------------------------------------------------------
// Three-phase structure
// ---------------------------------------------------------------------------
// Prologue -- if offset is not 8-byte aligned, extract
// min(length, 8-(offset%8)) bytes via predicated byte stores.
// Main -- process full 8-byte groups: load even/odd lane pair,
// de-interleave, scatter-store to output buffers.
// Tail -- extract remaining <8 bytes via predicated byte stores.
#include "../../../../common.h"
#if defined(MLK_FIPS202_ARMV81M_NEED_X4) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/armv81m/src/state_extract_bytes_x4_mve.S using scripts/simpasm. Do not modify it directly.
*/
.thumb
.syntax unified
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x4_state_extract_bytes_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x4_state_extract_bytes_asm)
.cfi_startproc
push.w {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
.cfi_adjust_cfa_offset 0x28
.cfi_rel_offset r4, 0x0
.cfi_rel_offset r5, 0x4
.cfi_rel_offset r6, 0x8
.cfi_rel_offset r7, 0xc
.cfi_rel_offset r8, 0x10
.cfi_rel_offset r9, 0x14
.cfi_rel_offset r10, 0x18
.cfi_rel_offset r11, 0x1c
.cfi_rel_offset lr, 0x24
vpush {d8, d9, d10, d11, d12, d13, d14, d15}
.cfi_adjust_cfa_offset 0x40
.cfi_rel_offset d8, 0x0
.cfi_rel_offset d9, 0x8
.cfi_rel_offset d10, 0x10
.cfi_rel_offset d11, 0x18
.cfi_rel_offset d12, 0x20
.cfi_rel_offset d13, 0x28
.cfi_rel_offset d14, 0x30
.cfi_rel_offset d15, 0x38
ldr r4, [sp, #0x68]
ldr.w r10, [sp, #0x6c]
ldr r6, [sp, #0x70]
cmp r6, #0x0
beq.w Lkeccak_f1600_x4_state_extract_bytes_asm_exit @ imm = #0x2ea
and r5, r10, #0x7
bic r9, r10, #0x7
add.w r8, r0, r9, lsl #1
add.w r7, r8, #0x190
cmp r5, #0x0
beq.w Lkeccak_f1600_x4_state_extract_bytes_asm_pre_main @ imm = #0x112
vldrw.u32 q0, [r8], #16
vldrw.u32 q1, [r7], #16
vrev32.16 q2, q0
vrev32.16 q3, q1
vsli.32 q0, q0, #0x8
vsli.16 q0, q0, #0x4
vsli.8 q0, q0, #0x1
vshr.u8 q4, q0, #0x3
vsli.8 q0, q4, #0x4
vshr.u8 q4, q0, #0x5
vsli.8 q0, q4, #0x6
vsli.32 q1, q1, #0x8
vsli.16 q1, q1, #0x4
vsli.8 q1, q1, #0x1
vshr.u8 q4, q1, #0x3
vsli.8 q1, q4, #0x4
vshr.u8 q4, q1, #0x5
vsli.8 q1, q4, #0x6
mov.w r0, #0x55
vdup.8 q4, r0
vand q0, q0, q4
vand q1, q1, q4
vshl.i32 q1, q1, #0x1
vorr q0, q0, q1
vsli.32 q2, q2, #0x8
vsli.16 q2, q2, #0x4
vsli.8 q2, q2, #0x1
vshr.u8 q1, q2, #0x3
vsli.8 q2, q1, #0x4
vshr.u8 q1, q2, #0x5
vsli.8 q2, q1, #0x6
vsli.32 q3, q3, #0x8
vsli.16 q3, q3, #0x4
vsli.8 q3, q3, #0x1
vshr.u8 q1, q3, #0x3
vsli.8 q3, q1, #0x4
vshr.u8 q1, q3, #0x5
vsli.8 q3, q1, #0x6
vand q1, q2, q4
vand q3, q3, q4
vshl.i32 q3, q3, #0x1
vorr q1, q1, q3
vrev64.32 q2, q0
vrev64.32 q3, q1
movw r0, #0xf0f
vmsr p0, r0
vpsel q0, q0, q3
vpsel q1, q2, q1
vmov.f64 d4, d1
vmov.f64 d6, d3
rsb.w lr, r5, #0x8
cmp r6, lr
it ls
movls lr, r6
vctp.8 lr
vmrs r11, p0
lsl.w r11, r11, r5
vmsr p0, r11
subs r1, r1, r5
subs r2, r2, r5
subs r3, r3, r5
subs r4, r4, r5
vpstttt
vstrbt.8 q0, [r1], #4
vstrbt.8 q1, [r2], #4
vstrbt.8 q2, [r3], #4
vstrbt.8 q3, [r4], #4
subs.w r6, r6, lr
cmp r6, #0x0
beq.w Lkeccak_f1600_x4_state_extract_bytes_asm_exit @ imm = #0x1cc
vmov q7[2], q7[0], r1, r3
vmov q7[3], q7[1], r2, r4
b Lkeccak_f1600_x4_state_extract_bytes_asm_main_body @ imm = #0xe
Lkeccak_f1600_x4_state_extract_bytes_asm_pre_main:
vmov q7[2], q7[0], r1, r3
vmov q7[3], q7[1], r2, r4
mov.w r12, #0x4
vsub.i32 q7, q7, r12
Lkeccak_f1600_x4_state_extract_bytes_asm_main_body:
lsr.w lr, r6, #0x3
wls lr, lr, Lkeccak_f1600_x4_state_extract_bytes_asm_main_loop_end @ imm = #0xb4
Lkeccak_f1600_x4_state_extract_bytes_asm_main_loop_start:
vldrw.u32 q0, [r8], #16
vldrw.u32 q1, [r7], #16
vrev32.16 q2, q0
vrev32.16 q3, q1
vsli.32 q0, q0, #0x8
vsli.16 q0, q0, #0x4
vsli.8 q0, q0, #0x1
vshr.u8 q4, q0, #0x3
vsli.8 q0, q4, #0x4
vshr.u8 q4, q0, #0x5
vsli.8 q0, q4, #0x6
vsli.32 q1, q1, #0x8
vsli.16 q1, q1, #0x4
vsli.8 q1, q1, #0x1
vshr.u8 q4, q1, #0x3
vsli.8 q1, q4, #0x4
vshr.u8 q4, q1, #0x5
vsli.8 q1, q4, #0x6
mov.w r0, #0x55
vdup.8 q4, r0
vand q0, q0, q4
vand q1, q1, q4
vshl.i32 q1, q1, #0x1
vorr q0, q0, q1
vsli.32 q2, q2, #0x8
vsli.16 q2, q2, #0x4
vsli.8 q2, q2, #0x1
vshr.u8 q1, q2, #0x3
vsli.8 q2, q1, #0x4
vshr.u8 q1, q2, #0x5
vsli.8 q2, q1, #0x6
vsli.32 q3, q3, #0x8
vsli.16 q3, q3, #0x4
vsli.8 q3, q3, #0x1
vshr.u8 q1, q3, #0x3
vsli.8 q3, q1, #0x4
vshr.u8 q1, q3, #0x5
vsli.8 q3, q1, #0x6
vand q1, q2, q4
vand q3, q3, q4
vshl.i32 q3, q3, #0x1
vorr q1, q1, q3
vstrw.32 q0, [q7, #4]!
vstrw.32 q1, [q7, #4]!
le lr, Lkeccak_f1600_x4_state_extract_bytes_asm_main_loop_start @ imm = #-0xb4
Lkeccak_f1600_x4_state_extract_bytes_asm_main_loop_end:
ands r6, r6, #0x7
beq Lkeccak_f1600_x4_state_extract_bytes_asm_exit @ imm = #0xee
mov.w r12, #0x4
vadd.i32 q7, q7, r12
vmov r1, r3, q7[2], q7[0]
vmov r2, r4, q7[3], q7[1]
vldrw.u32 q0, [r8], #16
vldrw.u32 q1, [r7], #16
vrev32.16 q2, q0
vrev32.16 q3, q1
vsli.32 q0, q0, #0x8
vsli.16 q0, q0, #0x4
vsli.8 q0, q0, #0x1
vshr.u8 q4, q0, #0x3
vsli.8 q0, q4, #0x4
vshr.u8 q4, q0, #0x5
vsli.8 q0, q4, #0x6
vsli.32 q1, q1, #0x8
vsli.16 q1, q1, #0x4
vsli.8 q1, q1, #0x1
vshr.u8 q4, q1, #0x3
vsli.8 q1, q4, #0x4
vshr.u8 q4, q1, #0x5
vsli.8 q1, q4, #0x6
mov.w r0, #0x55
vdup.8 q4, r0
vand q0, q0, q4
vand q1, q1, q4
vshl.i32 q1, q1, #0x1
vorr q0, q0, q1
vsli.32 q2, q2, #0x8
vsli.16 q2, q2, #0x4
vsli.8 q2, q2, #0x1
vshr.u8 q1, q2, #0x3
vsli.8 q2, q1, #0x4
vshr.u8 q1, q2, #0x5
vsli.8 q2, q1, #0x6
vsli.32 q3, q3, #0x8
vsli.16 q3, q3, #0x4
vsli.8 q3, q3, #0x1
vshr.u8 q1, q3, #0x3
vsli.8 q3, q1, #0x4
vshr.u8 q1, q3, #0x5
vsli.8 q3, q1, #0x6
vand q1, q2, q4
vand q3, q3, q4
vshl.i32 q3, q3, #0x1
vorr q1, q1, q3
vrev64.32 q2, q0
vrev64.32 q3, q1
movw r0, #0xf0f
vmsr p0, r0
vpsel q0, q0, q3
vpsel q1, q2, q1
vmov.f64 d4, d1
vmov.f64 d6, d3
vctp.8 r6
vpstttt
vstrbt.8 q0, [r1], #4
vstrbt.8 q1, [r2], #4
vstrbt.8 q2, [r3], #4
vstrbt.8 q3, [r4], #4
Lkeccak_f1600_x4_state_extract_bytes_asm_exit:
vpop {d8, d9, d10, d11, d12, d13, d14, d15}
.cfi_restore d8
.cfi_restore d9
.cfi_restore d10
.cfi_restore d11
.cfi_restore d12
.cfi_restore d13
.cfi_restore d14
.cfi_restore d15
.cfi_adjust_cfa_offset -0x40
pop.w {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}
.cfi_restore r4
.cfi_restore r5
.cfi_restore r6
.cfi_restore r7
.cfi_restore r8
.cfi_restore r9
.cfi_restore r10
.cfi_restore r11
.cfi_restore lr
.cfi_adjust_cfa_offset -0x28
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x4_state_extract_bytes_asm)
#endif /* MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,355 @@
/*
* Copyright (c) The mlkem-native project authors
* Copyright (c) The mldsa-native project authors
* Copyright (c) 2026 Arm Limited
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
// ---------------------------------------------------------------------------
// Overview
// ---------------------------------------------------------------------------
// MVE/Helium implementation of KeccakF1600x4_StateXORBytes.
//
// void KeccakF1600x4_StateXORBytes(state, d0, d1, d2, d3, offset, length)
//
// Reads 'length' plain bytes from each of four input buffers (d0..d3),
// splits every byte into its even and odd bits (bit-interleaving), and
// XORs the result into the Keccak state starting at byte 'offset'.
//
// ---------------------------------------------------------------------------
// Bit-interleaving background
// ---------------------------------------------------------------------------
// Each 64-bit Keccak lane is stored as two 32-bit words:
// even half -- bits 0, 2, 4, ..., 62 of the lane
// odd half -- bits 1, 3, 5, ..., 63 of the lane
// This representation allows 64-bit lane rotations (used in the Keccak
// round function) to be implemented as pairs of 32-bit rotations.
//
// Batched (x4) processing:
// Four Keccak instances are processed as a batch. Their states are
// stored interleaved in a single 800-byte buffer: first the even
// halves of all 25 lanes (400 bytes), then the odd halves (400 bytes).
// Within each 16-byte row, the four u32 words correspond to
// instances 0..3 of the same lane, enabling SIMD-parallel operations
// across all four instances.
//
// State memory layout (25 lanes x 4 instances x 2 halves):
// S[i][l]_even/odd = even/odd half of lane l, instance i (u32)
// Each row is 16 bytes (one Q-register).
// Offset Contents
// 0 S[0][ 0]_even, S[1][ 0]_even, S[2][ 0]_even, S[3][ 0]_even
// 16 S[0][ 1]_even, S[1][ 1]_even, S[2][ 1]_even, S[3][ 1]_even
// ...
// 384 S[0][24]_even, S[1][24]_even, S[2][24]_even, S[3][24]_even
// 400 S[0][ 0]_odd, S[1][ 0]_odd, S[2][ 0]_odd, S[3][ 0]_odd
// 416 S[0][ 1]_odd, S[1][ 1]_odd, S[2][ 1]_odd, S[3][ 1]_odd
// ...
// 784 S[0][24]_odd, S[1][24]_odd, S[2][24]_odd, S[3][24]_odd
//
// ---------------------------------------------------------------------------
// Three-phase structure
// ---------------------------------------------------------------------------
// Prologue -- if offset is not 8-byte aligned, absorb
// min(length, 8-(offset%8)) bytes via predicated byte loads.
// Main -- process full 8-byte groups via word-level gather loads,
// bit-interleave, then VEOR into even/odd state halves.
// Tail -- absorb remaining <8 bytes via predicated byte loads.
#include "../../../../common.h"
#if defined(MLK_FIPS202_ARMV81M_NEED_X4) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/armv81m/src/state_xor_bytes_x4_mve.S using scripts/simpasm. Do not modify it directly.
*/
.thumb
.syntax unified
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x4_state_xor_bytes_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x4_state_xor_bytes_asm)
.cfi_startproc
push.w {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
.cfi_adjust_cfa_offset 0x28
.cfi_rel_offset r4, 0x0
.cfi_rel_offset r5, 0x4
.cfi_rel_offset r6, 0x8
.cfi_rel_offset r7, 0xc
.cfi_rel_offset r8, 0x10
.cfi_rel_offset r9, 0x14
.cfi_rel_offset r10, 0x18
.cfi_rel_offset r11, 0x1c
.cfi_rel_offset lr, 0x24
vpush {d8, d9, d10, d11, d12, d13, d14, d15}
.cfi_adjust_cfa_offset 0x40
.cfi_rel_offset d8, 0x0
.cfi_rel_offset d9, 0x8
.cfi_rel_offset d10, 0x10
.cfi_rel_offset d11, 0x18
.cfi_rel_offset d12, 0x20
.cfi_rel_offset d13, 0x28
.cfi_rel_offset d14, 0x30
.cfi_rel_offset d15, 0x38
ldr r4, [sp, #0x68]
ldr.w r10, [sp, #0x6c]
ldr r6, [sp, #0x70]
cmp r6, #0x0
beq.w Lkeccak_f1600_x4_state_xor_bytes_asm_exit @ imm = #0x346
and r5, r10, #0x7
bic r9, r10, #0x7
add.w r8, r0, r9, lsl #1
add.w r7, r8, #0x190
cmp r5, #0x0
beq.w Lkeccak_f1600_x4_state_xor_bytes_asm_pre_main @ imm = #0x12c
subs r1, r1, r5
subs r2, r2, r5
subs r3, r3, r5
subs r4, r4, r5
rsb.w lr, r5, #0x8
cmp r6, lr
it ls
movls lr, r6
subs.w r6, r6, lr
vctp.8 lr
vmrs r11, p0
lsl.w r11, r11, r5
vmsr p0, r11
vpstttt
vldrbt.u8 q0, [r1], #4
vldrbt.u8 q1, [r2], #4
vldrbt.u8 q2, [r3], #4
vldrbt.u8 q3, [r4], #4
vmov.f64 d1, d4
vmov.f64 d3, d6
vrev64.32 q2, q0
vrev64.32 q3, q1
movw r0, #0xf0f
vmsr p0, r0
vpsel q0, q0, q3
vpsel q1, q2, q1
vmov q2, q0
vmov q3, q1
vshr.u8 q4, q0, #0x2
vsli.8 q0, q4, #0x1
vshr.u8 q4, q0, #0x3
vsli.8 q0, q4, #0x2
vshr.u8 q4, q0, #0x4
vsli.8 q0, q4, #0x3
vshr.u16 q4, q0, #0x8
vsli.8 q0, q4, #0x4
vshr.u32 q4, q0, #0x10
vsli.16 q0, q4, #0x8
vshr.u8 q4, q3, #0x2
vsli.8 q3, q4, #0x1
vshr.u8 q4, q3, #0x3
vsli.8 q3, q4, #0x2
vshr.u8 q4, q3, #0x4
vsli.8 q3, q4, #0x3
vshr.u16 q4, q3, #0x8
vsli.8 q3, q4, #0x4
vshr.u32 q4, q3, #0x10
vsli.16 q3, q4, #0x8
vsli.32 q0, q3, #0x10
vshl.i8 q4, q2, #0x2
vsri.8 q2, q4, #0x1
vshl.i8 q4, q2, #0x3
vsri.8 q2, q4, #0x2
vshl.i8 q4, q2, #0x4
vsri.8 q2, q4, #0x3
vshl.i16 q4, q2, #0x8
vsri.8 q2, q4, #0x4
vshl.i32 q4, q2, #0x10
vsri.16 q2, q4, #0x8
vshl.i8 q4, q1, #0x2
vsri.8 q1, q4, #0x1
vshl.i8 q4, q1, #0x3
vsri.8 q1, q4, #0x2
vshl.i8 q4, q1, #0x4
vsri.8 q1, q4, #0x3
vshl.i16 q4, q1, #0x8
vsri.8 q1, q4, #0x4
vshl.i32 q4, q1, #0x10
vsri.16 q1, q4, #0x8
vsri.32 q1, q2, #0x10
vldrw.u32 q4, [r8]
vldrw.u32 q5, [r7]
veor q4, q4, q0
veor q5, q5, q1
vstrw.32 q4, [r8], #16
vstrw.32 q5, [r7], #16
vmov q7[2], q7[0], r1, r3
vmov q7[3], q7[1], r2, r4
b Lkeccak_f1600_x4_state_xor_bytes_asm_main_body @ imm = #0xe
Lkeccak_f1600_x4_state_xor_bytes_asm_pre_main:
vmov q7[2], q7[0], r1, r3
vmov q7[3], q7[1], r2, r4
mov.w r0, #0x4
vsub.i32 q7, q7, r0
Lkeccak_f1600_x4_state_xor_bytes_asm_main_body:
lsr.w lr, r6, #0x3
wls lr, lr, Lkeccak_f1600_x4_state_xor_bytes_asm_main_loop_end @ imm = #0xd4
Lkeccak_f1600_x4_state_xor_bytes_asm_main_loop_start:
vldrw.u32 q0, [q7, #4]!
vldrw.u32 q1, [q7, #4]!
vmov q2, q0
vmov q3, q1
vshr.u8 q4, q0, #0x2
vsli.8 q0, q4, #0x1
vshr.u8 q4, q0, #0x3
vsli.8 q0, q4, #0x2
vshr.u8 q4, q0, #0x4
vsli.8 q0, q4, #0x3
vshr.u16 q4, q0, #0x8
vsli.8 q0, q4, #0x4
vshr.u32 q4, q0, #0x10
vsli.16 q0, q4, #0x8
vshr.u8 q4, q3, #0x2
vsli.8 q3, q4, #0x1
vshr.u8 q4, q3, #0x3
vsli.8 q3, q4, #0x2
vshr.u8 q4, q3, #0x4
vsli.8 q3, q4, #0x3
vshr.u16 q4, q3, #0x8
vsli.8 q3, q4, #0x4
vshr.u32 q4, q3, #0x10
vsli.16 q3, q4, #0x8
vsli.32 q0, q3, #0x10
vshl.i8 q4, q2, #0x2
vsri.8 q2, q4, #0x1
vshl.i8 q4, q2, #0x3
vsri.8 q2, q4, #0x2
vshl.i8 q4, q2, #0x4
vsri.8 q2, q4, #0x3
vshl.i16 q4, q2, #0x8
vsri.8 q2, q4, #0x4
vshl.i32 q4, q2, #0x10
vsri.16 q2, q4, #0x8
vshl.i8 q4, q1, #0x2
vsri.8 q1, q4, #0x1
vshl.i8 q4, q1, #0x3
vsri.8 q1, q4, #0x2
vshl.i8 q4, q1, #0x4
vsri.8 q1, q4, #0x3
vshl.i16 q4, q1, #0x8
vsri.8 q1, q4, #0x4
vshl.i32 q4, q1, #0x10
vsri.16 q1, q4, #0x8
vsri.32 q1, q2, #0x10
vldrw.u32 q4, [r8]
vldrw.u32 q5, [r7]
veor q4, q4, q0
veor q5, q5, q1
vstrw.32 q4, [r8], #16
vstrw.32 q5, [r7], #16
le lr, Lkeccak_f1600_x4_state_xor_bytes_asm_main_loop_start @ imm = #-0xd4
Lkeccak_f1600_x4_state_xor_bytes_asm_main_loop_end:
ands r6, r6, #0x7
beq.w Lkeccak_f1600_x4_state_xor_bytes_asm_exit @ imm = #0x110
mov.w r0, #0x4
vadd.i32 q7, q7, r0
vmov r1, r3, q7[2], q7[0]
vmov r2, r4, q7[3], q7[1]
vctp.8 r6
vpstttt
vldrbt.u8 q0, [r1]
vldrbt.u8 q1, [r2]
vldrbt.u8 q2, [r3]
vldrbt.u8 q3, [r4]
vmov.f64 d1, d4
vmov.f64 d3, d6
vrev64.32 q2, q0
vrev64.32 q3, q1
movw r0, #0xf0f
vmsr p0, r0
vpsel q0, q0, q3
vpsel q1, q2, q1
vmov q2, q0
vmov q3, q1
vshr.u8 q4, q0, #0x2
vsli.8 q0, q4, #0x1
vshr.u8 q4, q0, #0x3
vsli.8 q0, q4, #0x2
vshr.u8 q4, q0, #0x4
vsli.8 q0, q4, #0x3
vshr.u16 q4, q0, #0x8
vsli.8 q0, q4, #0x4
vshr.u32 q4, q0, #0x10
vsli.16 q0, q4, #0x8
vshr.u8 q4, q3, #0x2
vsli.8 q3, q4, #0x1
vshr.u8 q4, q3, #0x3
vsli.8 q3, q4, #0x2
vshr.u8 q4, q3, #0x4
vsli.8 q3, q4, #0x3
vshr.u16 q4, q3, #0x8
vsli.8 q3, q4, #0x4
vshr.u32 q4, q3, #0x10
vsli.16 q3, q4, #0x8
vsli.32 q0, q3, #0x10
vshl.i8 q4, q2, #0x2
vsri.8 q2, q4, #0x1
vshl.i8 q4, q2, #0x3
vsri.8 q2, q4, #0x2
vshl.i8 q4, q2, #0x4
vsri.8 q2, q4, #0x3
vshl.i16 q4, q2, #0x8
vsri.8 q2, q4, #0x4
vshl.i32 q4, q2, #0x10
vsri.16 q2, q4, #0x8
vshl.i8 q4, q1, #0x2
vsri.8 q1, q4, #0x1
vshl.i8 q4, q1, #0x3
vsri.8 q1, q4, #0x2
vshl.i8 q4, q1, #0x4
vsri.8 q1, q4, #0x3
vshl.i16 q4, q1, #0x8
vsri.8 q1, q4, #0x4
vshl.i32 q4, q1, #0x10
vsri.16 q1, q4, #0x8
vsri.32 q1, q2, #0x10
vldrw.u32 q4, [r8]
vldrw.u32 q5, [r7]
veor q4, q4, q0
veor q5, q5, q1
vstrw.32 q4, [r8], #16
vstrw.32 q5, [r7], #16
Lkeccak_f1600_x4_state_xor_bytes_asm_exit:
vpop {d8, d9, d10, d11, d12, d13, d14, d15}
.cfi_restore d8
.cfi_restore d9
.cfi_restore d10
.cfi_restore d11
.cfi_restore d12
.cfi_restore d13
.cfi_restore d14
.cfi_restore d15
.cfi_adjust_cfa_offset -0x40
pop.w {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}
.cfi_restore r4
.cfi_restore r5
.cfi_restore r6
.cfi_restore r7
.cfi_restore r8
.cfi_restore r9
.cfi_restore r10
.cfi_restore r11
.cfi_restore lr
.cfi_adjust_cfa_offset -0x28
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x4_state_xor_bytes_asm)
#endif /* MLK_FIPS202_ARMV81M_NEED_X4 && !MLK_CONFIG_MULTILEVEL_NO_SHARED */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_AUTO_H
#define MLK_FIPS202_NATIVE_AUTO_H
/*
* Default FIPS202 backend
*/
#include "../../sys.h"
#if defined(MLK_SYS_AARCH64)
#include "aarch64/auto.h"
#endif
/* The x86_64 backend requires toolchain support for the SysV ABI */
#if defined(MLK_SYS_X86_64_AVX2) && defined(MLK_SYSV_ABI_SUPPORTED)
#include "x86_64/keccak_f1600_x4_avx2.h"
#endif
/* We do not yet include the FIPS202 backend for Armv8.1-M+MVE by default
* as it is still experimental and undergoing review. */
/* #if defined(MLK_SYS_ARMV81M_MVE) */
/* #include "armv81m/mve.h" */
/* #endif */
#endif /* !MLK_FIPS202_NATIVE_AUTO_H */

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_X86_64_KECCAK_F1600_X4_AVX2_H
#define MLK_FIPS202_NATIVE_X86_64_KECCAK_F1600_X4_AVX2_H
#include "../../../common.h"
#define MLK_FIPS202_X86_64_NEED_X4_AVX2
/* Part of backend API */
#define MLK_USE_FIPS202_X4_NATIVE
#if !defined(__ASSEMBLER__)
#include "../api.h"
#include "src/fips202_native_x86_64.h"
MLK_MUST_CHECK_RETURN_VALUE
static MLK_INLINE int mlk_keccak_f1600_x4_native(uint64_t *state)
{
if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
{
return MLK_NATIVE_FUNC_FALLBACK;
}
mlk_keccak_f1600_x4_avx2_asm(state, mlk_keccakf1600_round_constants,
mlk_keccak_rho8, mlk_keccak_rho56);
return MLK_NATIVE_FUNC_SUCCESS;
}
#endif /* !__ASSEMBLER__ */
#endif /* !MLK_FIPS202_NATIVE_X86_64_KECCAK_F1600_X4_AVX2_H */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#ifndef MLK_FIPS202_NATIVE_X86_64_SRC_FIPS202_NATIVE_X86_64_H
#define MLK_FIPS202_NATIVE_X86_64_SRC_FIPS202_NATIVE_X86_64_H
#include "../../../../cbmc.h"
#include "../../../../common.h"
/* TODO: Reconsider whether this check is needed -- x86_64 is always
* little-endian, so the backend selection already implies this. */
#ifndef MLK_SYS_LITTLE_ENDIAN
#error Expecting a little-endian platform
#endif
#define mlk_keccakf1600_round_constants \
MLK_NAMESPACE(keccakf1600_round_constants)
MLK_INTERNAL_DATA_DECLARATION const uint64_t
mlk_keccakf1600_round_constants[24];
#define mlk_keccak_rho8 MLK_NAMESPACE(keccak_rho8)
MLK_INTERNAL_DATA_DECLARATION const uint64_t mlk_keccak_rho8[4];
#define mlk_keccak_rho56 MLK_NAMESPACE(keccak_rho56)
MLK_INTERNAL_DATA_DECLARATION const uint64_t mlk_keccak_rho56[4];
#define mlk_keccak_f1600_x4_avx2_asm MLK_NAMESPACE(keccak_f1600_x4_avx2_asm)
MLK_SYSV_ABI
void mlk_keccak_f1600_x4_avx2_asm(uint64_t states[100], const uint64_t rc[24],
const uint64_t rho8[4],
const uint64_t rho56[4])
/* This must be kept in sync with the HOL-Light specification
* in proofs/hol_light/x86_64/proofs/keccak_f1600_x4_avx2_asm.ml */
__contract__(
requires(memory_no_alias(states, sizeof(uint64_t) * 25 * 4))
requires(rc == mlk_keccakf1600_round_constants)
requires(rho8 == mlk_keccak_rho8)
requires(rho56 == mlk_keccak_rho56)
assigns(memory_slice(states, sizeof(uint64_t) * 25 * 4))
);
#endif /* !MLK_FIPS202_NATIVE_X86_64_SRC_FIPS202_NATIVE_X86_64_H */

View File

@@ -0,0 +1,487 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
#include "../../../../common.h"
#if defined(MLK_FIPS202_X86_64_NEED_X4_AVX2) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
/*yaml
Name: keccak_f1600_x4_avx2_asm
Description: x86_64 AVX2 Keccak-f[1600] permutation for four sequential states
Signature: void mlk_keccak_f1600_x4_avx2_asm(uint64_t states[100], const uint64_t rc[24], const uint64_t rho8[4], const uint64_t rho56[4])
ABI:
Architecture: x86_64
CallingConvention: SysV
Features: [AVX2]
rdi:
type: buffer
size_bytes: 800
permissions: read/write
c_parameter: uint64_t states[100]
description: Four sequential Keccak states (4 x 25 x uint64_t)
rsi:
type: buffer
size_bytes: 192
permissions: read-only
c_parameter: const uint64_t rc[24]
description: Round constants (24 x uint64_t)
rdx:
type: buffer
size_bytes: 32
permissions: read-only
c_parameter: const uint64_t rho8[4]
description: Rotation constant rho8 (4 x uint64_t)
rcx:
type: buffer
size_bytes: 32
permissions: read-only
c_parameter: const uint64_t rho56[4]
description: Rotation constant rho56 (4 x uint64_t)
*/
/*
* WARNING: This file is auto-derived from the mlkem-native source file
* dev/fips202/x86_64/src/keccak_f1600_x4_avx2_asm.S using scripts/simpasm. Do not modify it directly.
*/
.text
.balign 4
.global MLK_ASM_NAMESPACE(keccak_f1600_x4_avx2_asm)
MLK_ASM_FN_SYMBOL(keccak_f1600_x4_avx2_asm)
.cfi_startproc
movq %rsp, %r11
.cfi_def_cfa_register %r11
andq $-0x20, %rsp
subq $0x300, %rsp # imm = 0x300
vmovdqu (%rdi), %ymm0
vmovdqu 0xc8(%rdi), %ymm3
vmovdqu 0x190(%rdi), %ymm1
vmovdqu 0x258(%rdi), %ymm4
vpunpcklqdq %ymm3, %ymm0, %ymm2 # ymm2 = ymm0[0],ymm3[0],ymm0[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm3[1],ymm0[3],ymm3[3]
vpunpcklqdq %ymm4, %ymm1, %ymm3 # ymm3 = ymm1[0],ymm4[0],ymm1[2],ymm4[2]
vperm2i128 $0x20, %ymm3, %ymm2, %ymm7 # ymm7 = ymm2[0,1],ymm3[0,1]
vpunpckhqdq %ymm4, %ymm1, %ymm1 # ymm1 = ymm1[1],ymm4[1],ymm1[3],ymm4[3]
vperm2i128 $0x31, %ymm3, %ymm2, %ymm3 # ymm3 = ymm2[2,3],ymm3[2,3]
vmovdqu 0x278(%rdi), %ymm4
vmovdqu %ymm3, 0x40(%rsp)
vperm2i128 $0x31, %ymm1, %ymm0, %ymm3 # ymm3 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm7, (%rsp)
vperm2i128 $0x20, %ymm1, %ymm0, %ymm7 # ymm7 = ymm0[0,1],ymm1[0,1]
vmovdqu 0x20(%rdi), %ymm0
vmovdqu 0x1b0(%rdi), %ymm1
vmovdqu %ymm3, 0x60(%rsp)
vmovdqu 0xe8(%rdi), %ymm3
vmovdqu %ymm7, 0x20(%rsp)
vpunpcklqdq %ymm3, %ymm0, %ymm2 # ymm2 = ymm0[0],ymm3[0],ymm0[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm3[1],ymm0[3],ymm3[3]
vpunpcklqdq %ymm4, %ymm1, %ymm3 # ymm3 = ymm1[0],ymm4[0],ymm1[2],ymm4[2]
vperm2i128 $0x20, %ymm3, %ymm2, %ymm7 # ymm7 = ymm2[0,1],ymm3[0,1]
vpunpckhqdq %ymm4, %ymm1, %ymm1 # ymm1 = ymm1[1],ymm4[1],ymm1[3],ymm4[3]
vperm2i128 $0x31, %ymm3, %ymm2, %ymm3 # ymm3 = ymm2[2,3],ymm3[2,3]
vmovdqu 0x298(%rdi), %ymm4
vperm2i128 $0x31, %ymm1, %ymm0, %ymm14 # ymm14 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm7, 0x80(%rsp)
vperm2i128 $0x20, %ymm1, %ymm0, %ymm7 # ymm7 = ymm0[0,1],ymm1[0,1]
vmovdqu 0x40(%rdi), %ymm0
vmovdqu 0x1d0(%rdi), %ymm1
vmovdqu %ymm3, 0xc0(%rsp)
vmovdqu 0x108(%rdi), %ymm3
vmovdqu %ymm14, %ymm10
vmovdqu %ymm7, 0xa0(%rsp)
vpunpcklqdq %ymm3, %ymm0, %ymm2 # ymm2 = ymm0[0],ymm3[0],ymm0[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm3[1],ymm0[3],ymm3[3]
vpunpcklqdq %ymm4, %ymm1, %ymm3 # ymm3 = ymm1[0],ymm4[0],ymm1[2],ymm4[2]
vpunpckhqdq %ymm4, %ymm1, %ymm1 # ymm1 = ymm1[1],ymm4[1],ymm1[3],ymm4[3]
vperm2i128 $0x20, %ymm3, %ymm2, %ymm11 # ymm11 = ymm2[0,1],ymm3[0,1]
vperm2i128 $0x31, %ymm3, %ymm2, %ymm3 # ymm3 = ymm2[2,3],ymm3[2,3]
vperm2i128 $0x20, %ymm1, %ymm0, %ymm7 # ymm7 = ymm0[0,1],ymm1[0,1]
vmovdqu %ymm3, 0x100(%rsp)
vperm2i128 $0x31, %ymm1, %ymm0, %ymm8 # ymm8 = ymm0[2,3],ymm1[2,3]
vmovdqu 0x128(%rdi), %ymm3
vmovdqu 0x60(%rdi), %ymm0
vmovdqu 0x1f0(%rdi), %ymm1
vmovdqu %ymm7, 0xe0(%rsp)
vmovdqu %ymm11, %ymm14
vmovdqu 0x2b8(%rdi), %ymm4
vmovdqu 0x2f8(%rdi), %ymm5
vpunpcklqdq %ymm3, %ymm0, %ymm2 # ymm2 = ymm0[0],ymm3[0],ymm0[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm3[1],ymm0[3],ymm3[3]
vpunpcklqdq %ymm4, %ymm1, %ymm3 # ymm3 = ymm1[0],ymm4[0],ymm1[2],ymm4[2]
vpunpckhqdq %ymm4, %ymm1, %ymm1 # ymm1 = ymm1[1],ymm4[1],ymm1[3],ymm4[3]
vmovdqu 0x2d8(%rdi), %ymm4
vperm2i128 $0x20, %ymm3, %ymm2, %ymm15 # ymm15 = ymm2[0,1],ymm3[0,1]
vperm2i128 $0x31, %ymm3, %ymm2, %ymm3 # ymm3 = ymm2[2,3],ymm3[2,3]
vperm2i128 $0x20, %ymm1, %ymm0, %ymm7 # ymm7 = ymm0[0,1],ymm1[0,1]
vperm2i128 $0x31, %ymm1, %ymm0, %ymm9 # ymm9 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm3, 0x140(%rsp)
vmovdqu 0x80(%rdi), %ymm0
vmovdqu 0x148(%rdi), %ymm3
vmovdqu 0x210(%rdi), %ymm1
vmovdqu %ymm7, 0x120(%rsp)
vpunpcklqdq %ymm3, %ymm0, %ymm2 # ymm2 = ymm0[0],ymm3[0],ymm0[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm3[1],ymm0[3],ymm3[3]
vpunpcklqdq %ymm4, %ymm1, %ymm3 # ymm3 = ymm1[0],ymm4[0],ymm1[2],ymm4[2]
vpunpckhqdq %ymm4, %ymm1, %ymm1 # ymm1 = ymm1[1],ymm4[1],ymm1[3],ymm4[3]
vperm2i128 $0x20, %ymm3, %ymm2, %ymm7 # ymm7 = ymm2[0,1],ymm3[0,1]
vperm2i128 $0x31, %ymm3, %ymm2, %ymm13 # ymm13 = ymm2[2,3],ymm3[2,3]
vperm2i128 $0x31, %ymm1, %ymm0, %ymm3 # ymm3 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm7, 0x160(%rsp)
vperm2i128 $0x20, %ymm1, %ymm0, %ymm7 # ymm7 = ymm0[0,1],ymm1[0,1]
vmovdqu 0xa0(%rdi), %ymm0
vmovdqu 0x230(%rdi), %ymm1
vmovdqu %ymm3, 0x1a0(%rsp)
vmovdqu 0x168(%rdi), %ymm3
vpunpcklqdq %ymm5, %ymm1, %ymm4 # ymm4 = ymm1[0],ymm5[0],ymm1[2],ymm5[2]
vpunpckhqdq %ymm5, %ymm1, %ymm1 # ymm1 = ymm1[1],ymm5[1],ymm1[3],ymm5[3]
vmovdqu %ymm7, 0x180(%rsp)
vpunpcklqdq %ymm3, %ymm0, %ymm2 # ymm2 = ymm0[0],ymm3[0],ymm0[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm3[1],ymm0[3],ymm3[3]
vperm2i128 $0x20, %ymm4, %ymm2, %ymm12 # ymm12 = ymm2[0,1],ymm4[0,1]
vperm2i128 $0x20, %ymm1, %ymm0, %ymm3 # ymm3 = ymm0[0,1],ymm1[0,1]
vperm2i128 $0x31, %ymm4, %ymm2, %ymm7 # ymm7 = ymm2[2,3],ymm4[2,3]
vperm2i128 $0x31, %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[2,3],ymm1[2,3]
vmovq 0x250(%rdi), %xmm0
vmovq 0xc0(%rdi), %xmm1
vmovdqu %ymm12, 0x1c0(%rsp)
vmovdqu %ymm4, 0x1e0(%rsp)
vpinsrq $0x1, 0x318(%rdi), %xmm0, %xmm0
vpinsrq $0x1, 0x188(%rdi), %xmm1, %xmm1
vinserti128 $0x1, %xmm0, %ymm1, %ymm2
movq $0x0, %r10
LLkeccak_f1600_x4_avx2:
vmovdqu 0xa0(%rsp), %ymm4
vpxor 0x1c0(%rsp), %ymm9, %ymm0
vmovdqu %ymm9, 0x200(%rsp)
vmovdqu %ymm10, %ymm9
vmovdqu 0xc0(%rsp), %ymm11
vmovdqu 0x160(%rsp), %ymm12
vmovdqu %ymm3, 0x240(%rsp)
vpxor 0x100(%rsp), %ymm4, %ymm1
vmovdqu 0x40(%rsp), %ymm10
vmovdqu %ymm4, 0x220(%rsp)
vpxor %ymm3, %ymm12, %ymm12
vmovdqu 0x20(%rsp), %ymm6
vmovdqu 0x140(%rsp), %ymm4
vmovdqu %ymm14, 0x2a0(%rsp)
vpxor %ymm1, %ymm0, %ymm0
vpxor %ymm8, %ymm11, %ymm1
vpxor 0x180(%rsp), %ymm7, %ymm11
vmovdqu %ymm10, 0x280(%rsp)
vpxor %ymm1, %ymm12, %ymm12
vpxor %ymm15, %ymm9, %ymm1
vmovdqu 0xe0(%rsp), %ymm3
vmovdqu %ymm8, 0x260(%rsp)
vpxor %ymm1, %ymm11, %ymm11
vpxor 0x120(%rsp), %ymm14, %ymm1
vpxor %ymm6, %ymm12, %ymm12
vmovdqu 0x60(%rsp), %ymm8
vpxor %ymm10, %ymm11, %ymm11
vpxor 0x1e0(%rsp), %ymm13, %ymm10
vpxor %ymm4, %ymm3, %ymm3
vmovdqu %ymm4, 0x2c0(%rsp)
vpsrlq $0x3f, %ymm12, %ymm4
vpsrlq $0x3f, %ymm11, %ymm5
vpxor (%rsp), %ymm0, %ymm0
vpxor %ymm1, %ymm10, %ymm10
vmovdqu 0x80(%rsp), %ymm1
vpxor %ymm8, %ymm10, %ymm10
vmovdqu %ymm1, %ymm14
vpxor 0x1a0(%rsp), %ymm2, %ymm1
vmovdqu %ymm14, 0x2e0(%rsp)
vpxor %ymm3, %ymm1, %ymm1
vpsllq $0x1, %ymm12, %ymm3
vpor %ymm4, %ymm3, %ymm3
vpsllq $0x1, %ymm11, %ymm4
vpxor %ymm14, %ymm1, %ymm1
vpor %ymm5, %ymm4, %ymm4
vpsrlq $0x3f, %ymm10, %ymm14
vpxor %ymm1, %ymm3, %ymm3
vpsllq $0x1, %ymm10, %ymm5
vpxor %ymm0, %ymm4, %ymm4
vpor %ymm14, %ymm5, %ymm5
vpxor %ymm6, %ymm4, %ymm6
vpxor %ymm12, %ymm5, %ymm5
vpsrlq $0x3f, %ymm1, %ymm12
vpsllq $0x1, %ymm1, %ymm1
vpxor %ymm7, %ymm5, %ymm7
vpxor %ymm9, %ymm5, %ymm9
vpor %ymm12, %ymm1, %ymm1
vpxor (%rsp), %ymm3, %ymm12
vpxor %ymm11, %ymm1, %ymm1
vpsrlq $0x3f, %ymm0, %ymm11
vpsllq $0x1, %ymm0, %ymm0
vpxor %ymm13, %ymm1, %ymm13
vpxor %ymm8, %ymm1, %ymm8
vpor %ymm11, %ymm0, %ymm0
vpxor %ymm10, %ymm0, %ymm0
vpxor 0xc0(%rsp), %ymm4, %ymm10
vpxor %ymm2, %ymm0, %ymm2
vpsrlq $0x14, %ymm10, %ymm11
vpsllq $0x2c, %ymm10, %ymm10
vpor %ymm11, %ymm10, %ymm10
vpxor %ymm15, %ymm5, %ymm11
vpbroadcastq (%rsi), %ymm15
vpsrlq $0x15, %ymm11, %ymm14
vpsllq $0x2b, %ymm11, %ymm11
vpor %ymm14, %ymm11, %ymm11
vpandn %ymm11, %ymm10, %ymm14
vpxor %ymm15, %ymm14, %ymm14
vpxor %ymm12, %ymm14, %ymm15
vpsrlq $0x2b, %ymm13, %ymm14
vpsllq $0x15, %ymm13, %ymm13
vmovdqu %ymm15, (%rsp)
vpor %ymm14, %ymm13, %ymm13
vpandn %ymm13, %ymm11, %ymm14
vpxor %ymm10, %ymm14, %ymm15
vpsrlq $0x32, %ymm2, %ymm14
vpsllq $0xe, %ymm2, %ymm2
vmovdqu %ymm15, 0x20(%rsp)
vpor %ymm14, %ymm2, %ymm2
vpandn %ymm2, %ymm13, %ymm14
vpxor %ymm11, %ymm14, %ymm11
vmovdqu %ymm11, 0x40(%rsp)
vpandn %ymm12, %ymm2, %ymm11
vpandn %ymm10, %ymm12, %ymm12
vpxor %ymm13, %ymm11, %ymm11
vmovdqu %ymm11, 0x60(%rsp)
vpxor %ymm2, %ymm12, %ymm11
vpsrlq $0x24, %ymm8, %ymm2
vpsllq $0x1c, %ymm8, %ymm8
vmovdqu %ymm11, 0x80(%rsp)
vpor %ymm2, %ymm8, %ymm8
vpxor 0xe0(%rsp), %ymm0, %ymm2
vpsrlq $0x2c, %ymm2, %ymm10
vpsllq $0x14, %ymm2, %ymm2
vpor %ymm10, %ymm2, %ymm2
vpxor 0x100(%rsp), %ymm3, %ymm10
vpsrlq $0x3d, %ymm10, %ymm11
vpsllq $0x3, %ymm10, %ymm10
vpor %ymm11, %ymm10, %ymm10
vpandn %ymm10, %ymm2, %ymm11
vpxor %ymm8, %ymm11, %ymm11
vmovdqu %ymm11, 0xa0(%rsp)
vpxor 0x160(%rsp), %ymm4, %ymm11
vpsrlq $0x13, %ymm11, %ymm12
vpsllq $0x2d, %ymm11, %ymm11
vpor %ymm12, %ymm11, %ymm11
vpandn %ymm11, %ymm10, %ymm12
vpxor %ymm2, %ymm12, %ymm12
vmovdqu %ymm12, 0xc0(%rsp)
vpsrlq $0x3, %ymm7, %ymm12
vpsllq $0x3d, %ymm7, %ymm7
vpor %ymm12, %ymm7, %ymm7
vpandn %ymm7, %ymm11, %ymm12
vpxor %ymm10, %ymm12, %ymm10
vpandn %ymm8, %ymm7, %ymm12
vpandn %ymm2, %ymm8, %ymm8
vpsrlq $0x3f, %ymm6, %ymm2
vpsllq $0x1, %ymm6, %ymm6
vpxor %ymm11, %ymm12, %ymm14
vpor %ymm2, %ymm6, %ymm6
vpsrlq $0x3a, %ymm9, %ymm2
vpxor %ymm7, %ymm8, %ymm12
vpsllq $0x6, %ymm9, %ymm9
vmovdqu %ymm12, 0xe0(%rsp)
vpxor 0x1a0(%rsp), %ymm0, %ymm7
vpor %ymm2, %ymm9, %ymm9
vpxor 0x120(%rsp), %ymm1, %ymm2
vpshufb (%rdx), %ymm7, %ymm7
vpsrlq $0x27, %ymm2, %ymm11
vpsllq $0x19, %ymm2, %ymm2
vpor %ymm2, %ymm11, %ymm11
vpandn %ymm11, %ymm9, %ymm2
vpandn %ymm7, %ymm11, %ymm8
vpxor %ymm6, %ymm2, %ymm12
vpxor 0x1c0(%rsp), %ymm3, %ymm2
vpxor %ymm9, %ymm8, %ymm8
vmovdqu %ymm12, 0x100(%rsp)
vpsrlq $0x2e, %ymm2, %ymm12
vpsllq $0x12, %ymm2, %ymm2
vpor %ymm2, %ymm12, %ymm2
vpandn %ymm2, %ymm7, %ymm12
vpxor %ymm11, %ymm12, %ymm15
vpandn %ymm6, %ymm2, %ymm11
vpandn %ymm9, %ymm6, %ymm6
vpxor %ymm7, %ymm11, %ymm12
vmovdqu %ymm12, 0x120(%rsp)
vpxor %ymm2, %ymm6, %ymm12
vpxor 0x2e0(%rsp), %ymm0, %ymm6
vpxor 0x2c0(%rsp), %ymm0, %ymm0
vmovdqu %ymm12, 0x140(%rsp)
vpsrlq $0x25, %ymm6, %ymm2
vpsllq $0x1b, %ymm6, %ymm6
vpor %ymm6, %ymm2, %ymm2
vpxor 0x220(%rsp), %ymm3, %ymm6
vpxor 0x200(%rsp), %ymm3, %ymm3
vpsrlq $0x1c, %ymm6, %ymm7
vpsllq $0x24, %ymm6, %ymm6
vpor %ymm6, %ymm7, %ymm7
vpxor 0x260(%rsp), %ymm4, %ymm6
vpxor 0x240(%rsp), %ymm4, %ymm4
vpsrlq $0x36, %ymm6, %ymm12
vpsllq $0xa, %ymm6, %ymm6
vpor %ymm6, %ymm12, %ymm12
vpxor 0x180(%rsp), %ymm5, %ymm6
vpxor 0x280(%rsp), %ymm5, %ymm5
vpandn %ymm12, %ymm7, %ymm9
vpsrlq $0x31, %ymm6, %ymm11
vpsllq $0xf, %ymm6, %ymm6
vpxor %ymm2, %ymm9, %ymm9
vpor %ymm6, %ymm11, %ymm11
vpandn %ymm11, %ymm12, %ymm6
vpxor %ymm7, %ymm6, %ymm6
vmovdqu %ymm6, 0x160(%rsp)
vpxor 0x1e0(%rsp), %ymm1, %ymm6
vpxor 0x2a0(%rsp), %ymm1, %ymm1
vpshufb (%rcx), %ymm6, %ymm6
vpandn %ymm6, %ymm11, %ymm13
vpxor %ymm12, %ymm13, %ymm13
vmovdqu %ymm13, 0x180(%rsp)
vpandn %ymm2, %ymm6, %ymm13
vpandn %ymm7, %ymm2, %ymm2
vpxor %ymm6, %ymm2, %ymm2
vpsrlq $0x3e, %ymm4, %ymm6
vpxor %ymm11, %ymm13, %ymm13
vmovdqu %ymm2, 0x1a0(%rsp)
vpsrlq $0x2, %ymm5, %ymm2
vpsllq $0x3e, %ymm5, %ymm5
vpor %ymm5, %ymm2, %ymm2
vpsrlq $0x9, %ymm1, %ymm5
vpsllq $0x37, %ymm1, %ymm1
vpsllq $0x2, %ymm4, %ymm4
vpor %ymm1, %ymm5, %ymm1
vpsrlq $0x19, %ymm0, %ymm5
vpor %ymm4, %ymm6, %ymm4
vpsllq $0x27, %ymm0, %ymm0
vpor %ymm0, %ymm5, %ymm5
vpandn %ymm5, %ymm1, %ymm0
vpxor %ymm2, %ymm0, %ymm0
vmovdqu %ymm0, 0x1c0(%rsp)
vpsrlq $0x17, %ymm3, %ymm0
vpsllq $0x29, %ymm3, %ymm3
vpor %ymm3, %ymm0, %ymm0
vpandn %ymm4, %ymm0, %ymm7
vpandn %ymm0, %ymm5, %ymm3
vpxor %ymm5, %ymm7, %ymm7
vpandn %ymm2, %ymm4, %ymm5
vpandn %ymm1, %ymm2, %ymm2
vpxor %ymm0, %ymm5, %ymm5
vpxor %ymm1, %ymm3, %ymm3
vpxor %ymm4, %ymm2, %ymm2
vmovdqu %ymm5, 0x1e0(%rsp)
addq $0x8, %rsi
addq $0x1, %r10
cmpq $0x18, %r10
jne LLkeccak_f1600_x4_avx2
vmovdqu (%rsp), %ymm4
vmovdqu 0x40(%rsp), %ymm5
vmovdqu 0x20(%rsp), %ymm0
vmovdqu 0x60(%rsp), %ymm1
vmovdqu 0x1c0(%rsp), %ymm12
vmovdqu %ymm2, 0x1c0(%rsp)
vpunpcklqdq %ymm0, %ymm4, %ymm2 # ymm2 = ymm4[0],ymm0[0],ymm4[2],ymm0[2]
vpunpckhqdq %ymm0, %ymm4, %ymm0 # ymm0 = ymm4[1],ymm0[1],ymm4[3],ymm0[3]
vpunpcklqdq %ymm1, %ymm5, %ymm4 # ymm4 = ymm5[0],ymm1[0],ymm5[2],ymm1[2]
vpunpckhqdq %ymm1, %ymm5, %ymm1 # ymm1 = ymm5[1],ymm1[1],ymm5[3],ymm1[3]
vperm2i128 $0x20, %ymm4, %ymm2, %ymm6 # ymm6 = ymm2[0,1],ymm4[0,1]
vperm2i128 $0x31, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[2,3],ymm4[2,3]
vmovdqu 0x80(%rsp), %ymm4
vperm2i128 $0x20, %ymm1, %ymm0, %ymm5 # ymm5 = ymm0[0,1],ymm1[0,1]
vperm2i128 $0x31, %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm6, (%rdi)
vmovdqu %ymm5, 0xc8(%rdi)
vmovdqu %ymm2, 0x190(%rdi)
vmovdqu %ymm0, 0x258(%rdi)
vmovdqu 0xa0(%rsp), %ymm0
vpunpcklqdq %ymm0, %ymm4, %ymm2 # ymm2 = ymm4[0],ymm0[0],ymm4[2],ymm0[2]
vpunpckhqdq %ymm0, %ymm4, %ymm1 # ymm1 = ymm4[1],ymm0[1],ymm4[3],ymm0[3]
vmovdqu 0xc0(%rsp), %ymm0
vpunpcklqdq %ymm10, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm10[0],ymm0[2],ymm10[2]
vpunpckhqdq %ymm10, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm10[1],ymm0[3],ymm10[3]
vperm2i128 $0x20, %ymm4, %ymm2, %ymm6 # ymm6 = ymm2[0,1],ymm4[0,1]
vperm2i128 $0x20, %ymm0, %ymm1, %ymm5 # ymm5 = ymm1[0,1],ymm0[0,1]
vperm2i128 $0x31, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[2,3],ymm4[2,3]
vmovdqu 0xe0(%rsp), %ymm4
vperm2i128 $0x31, %ymm0, %ymm1, %ymm1 # ymm1 = ymm1[2,3],ymm0[2,3]
vmovdqu 0x100(%rsp), %ymm0
vmovdqu %ymm2, 0x1b0(%rdi)
vmovdqu %ymm1, 0x278(%rdi)
vpunpcklqdq %ymm4, %ymm14, %ymm2 # ymm2 = ymm14[0],ymm4[0],ymm14[2],ymm4[2]
vpunpckhqdq %ymm4, %ymm14, %ymm1 # ymm1 = ymm14[1],ymm4[1],ymm14[3],ymm4[3]
vpunpcklqdq %ymm8, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm8[0],ymm0[2],ymm8[2]
vpunpckhqdq %ymm8, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm8[1],ymm0[3],ymm8[3]
vmovdqu %ymm6, 0x20(%rdi)
vmovdqu %ymm5, 0xe8(%rdi)
vperm2i128 $0x20, %ymm4, %ymm2, %ymm6 # ymm6 = ymm2[0,1],ymm4[0,1]
vperm2i128 $0x20, %ymm0, %ymm1, %ymm5 # ymm5 = ymm1[0,1],ymm0[0,1]
vperm2i128 $0x31, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[2,3],ymm4[2,3]
vperm2i128 $0x31, %ymm0, %ymm1, %ymm1 # ymm1 = ymm1[2,3],ymm0[2,3]
vmovdqu 0x120(%rsp), %ymm4
vmovdqu 0x140(%rsp), %ymm0
vmovdqu %ymm2, 0x1d0(%rdi)
vmovdqu %ymm1, 0x298(%rdi)
vpunpcklqdq %ymm4, %ymm15, %ymm2 # ymm2 = ymm15[0],ymm4[0],ymm15[2],ymm4[2]
vpunpckhqdq %ymm4, %ymm15, %ymm1 # ymm1 = ymm15[1],ymm4[1],ymm15[3],ymm4[3]
vpunpcklqdq %ymm9, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm9[0],ymm0[2],ymm9[2]
vmovdqu %ymm5, 0x108(%rdi)
vpunpckhqdq %ymm9, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm9[1],ymm0[3],ymm9[3]
vmovdqu %ymm6, 0x40(%rdi)
vperm2i128 $0x20, %ymm4, %ymm2, %ymm6 # ymm6 = ymm2[0,1],ymm4[0,1]
vperm2i128 $0x31, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[2,3],ymm4[2,3]
vperm2i128 $0x20, %ymm0, %ymm1, %ymm5 # ymm5 = ymm1[0,1],ymm0[0,1]
vmovdqu 0x160(%rsp), %ymm4
vperm2i128 $0x31, %ymm0, %ymm1, %ymm1 # ymm1 = ymm1[2,3],ymm0[2,3]
vmovdqu 0x180(%rsp), %ymm0
vmovdqu %ymm5, 0x128(%rdi)
vmovdqu 0x1a0(%rsp), %ymm5
vmovdqu %ymm2, 0x1f0(%rdi)
vpunpcklqdq %ymm0, %ymm4, %ymm2 # ymm2 = ymm4[0],ymm0[0],ymm4[2],ymm0[2]
vpunpckhqdq %ymm0, %ymm4, %ymm0 # ymm0 = ymm4[1],ymm0[1],ymm4[3],ymm0[3]
vpunpcklqdq %ymm5, %ymm13, %ymm4 # ymm4 = ymm13[0],ymm5[0],ymm13[2],ymm5[2]
vmovdqu %ymm6, 0x60(%rdi)
vperm2i128 $0x20, %ymm4, %ymm2, %ymm6 # ymm6 = ymm2[0,1],ymm4[0,1]
vmovdqu %ymm1, 0x2b8(%rdi)
vperm2i128 $0x31, %ymm4, %ymm2, %ymm2 # ymm2 = ymm2[2,3],ymm4[2,3]
vpunpckhqdq %ymm5, %ymm13, %ymm1 # ymm1 = ymm13[1],ymm5[1],ymm13[3],ymm5[3]
vmovdqu %ymm6, 0x80(%rdi)
vmovdqu 0x1e0(%rsp), %ymm4
vperm2i128 $0x20, %ymm1, %ymm0, %ymm5 # ymm5 = ymm0[0,1],ymm1[0,1]
vperm2i128 $0x31, %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm2, 0x210(%rdi)
vpunpcklqdq %ymm3, %ymm12, %ymm2 # ymm2 = ymm12[0],ymm3[0],ymm12[2],ymm3[2]
vmovdqu %ymm0, 0x2d8(%rdi)
vpunpckhqdq %ymm3, %ymm12, %ymm0 # ymm0 = ymm12[1],ymm3[1],ymm12[3],ymm3[3]
vpunpcklqdq %ymm4, %ymm7, %ymm3 # ymm3 = ymm7[0],ymm4[0],ymm7[2],ymm4[2]
vpunpckhqdq %ymm4, %ymm7, %ymm1 # ymm1 = ymm7[1],ymm4[1],ymm7[3],ymm4[3]
vmovdqu %ymm5, 0x148(%rdi)
vperm2i128 $0x20, %ymm3, %ymm2, %ymm5 # ymm5 = ymm2[0,1],ymm3[0,1]
vperm2i128 $0x31, %ymm3, %ymm2, %ymm2 # ymm2 = ymm2[2,3],ymm3[2,3]
vmovdqu 0x1c0(%rsp), %ymm3
vperm2i128 $0x20, %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[0,1],ymm1[0,1]
vperm2i128 $0x31, %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm1[2,3]
vmovdqu %ymm5, 0xa0(%rdi)
vextracti128 $0x1, %ymm3, %xmm15
vmovdqu %ymm4, 0x168(%rdi)
vmovdqu %ymm2, 0x230(%rdi)
vmovdqu %ymm0, 0x2f8(%rdi)
vmovq %xmm3, 0xc0(%rdi)
vmovhpd %xmm3, 0x188(%rdi)
vmovq %xmm15, 0x250(%rdi)
vmovhpd %xmm15, 0x318(%rdi)
movq %r11, %rsp
.cfi_def_cfa_register %rsp
retq
.cfi_endproc
MLK_ASM_FN_SIZE(keccak_f1600_x4_avx2_asm)
#endif /* MLK_FIPS202_X86_64_NEED_X4_AVX2 && !MLK_CONFIG_MULTILEVEL_NO_SHARED */
#if defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
*/
/*
* WARNING: This file is auto-generated from scripts/autogen
* in the mlkem-native repository.
* Do not modify it directly.
*/
#include "../../../../common.h"
#if defined(MLK_FIPS202_X86_64_NEED_X4_AVX2) && \
!defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
#include <stdint.h>
#include "fips202_native_x86_64.h"
MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const uint64_t
mlk_keccakf1600_round_constants[24] = {
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
};
MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const uint64_t mlk_keccak_rho8[4] = {
0x0605040302010007,
0x0e0d0c0b0a09080f,
0x1615141312111017,
0x1e1d1c1b1a19181f,
};
MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const uint64_t mlk_keccak_rho56[4] = {
0x0007060504030201,
0x080f0e0d0c0b0a09,
0x1017161514131211,
0x181f1e1d1c1b1a19,
};
#else /* MLK_FIPS202_X86_64_NEED_X4_AVX2 && !MLK_CONFIG_MULTILEVEL_NO_SHARED \
*/
MLK_EMPTY_CU(fips202_x86_64_constants)
#endif /* !(MLK_FIPS202_X86_64_NEED_X4_AVX2 && \
!MLK_CONFIG_MULTILEVEL_NO_SHARED) */