From 665f02ee5a54168b41e432aa2e3fd8760db0be5c Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 16 Dec 2024 05:56:50 +0000 Subject: [PATCH 1/3] Introduce global config and reorganize backends This commit introduces a global configuration file `mlkem/config.h` which should contain all user-configurable parameters. With this commit, it contains: - MLKEM_K - MLKEM_NAMESPACE - FIPS202_NAMESPACE - MLKEM_USE_NATIVE - MLKEM_NATIVE_ARITH_BACKEND - MLKEM_NATIVE_FIPS202_BACKEND The backends have been reorganized to follow a simpler file structure: Every backend profile is identified by metadata file in the toplevel directory of the backend. For example, `aarch64` has `opt.h` and `clean.h`. Those metadata files so far only set the name of the backend, and point to the actual implementation. The reason why the metadata file and the implementation are kept separate is so that assembly files can include the metadata file and know if they should be assembled: For example, `aarch64/opt.h` sets `MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT` which all relevant files are guarded by; similar for clean. Previously, they were all guarded more coarsely by `MLKEM_USE_NATIVE_AARCH64` or `MLKEM_USE_NATIVE_X86_64` -- those have been removed. The source code of the backends has been moved into `src` directories. Ultimately, we may want to split `aarch64` into `aarch64_opt` and `aarch64_clean`, so the distinction between profile and backend goes away, but this is not yet attempted. Signed-off-by: Hanno Becker --- .github/workflows/bench.yml | 2 +- examples/bring_your_own_fips202/Makefile | 1 - .../custom_fips202/fips202.h | 2 +- .../custom_fips202/namespace.h | 30 ------ .../mlkem_native_as_code_package/Makefile | 1 - fips202/fips202.h | 3 +- fips202/fips202_backend.h | 18 ++++ fips202/fips202x4.h | 2 +- fips202/keccakf1600.c | 2 +- fips202/keccakf1600.h | 4 +- fips202/namespace.h | 30 ------ fips202/native/aarch64/cortex_a55.h | 24 +++++ fips202/native/aarch64/default.h | 24 +++++ fips202/native/aarch64/{ => src}/common.i | 0 .../cortex_a55.h => src/cortex_a55_impl.h} | 8 +- .../default.h => src/default_impl.h} | 6 +- .../{ => src}/fips202_native_aarch64.h | 6 +- .../keccak_f1600_x1_scalar_asm_opt.S | 9 +- .../keccak_f1600_x1_v84a_asm_clean.S | 5 +- .../keccak_f1600_x2_v84a_asm_clean.S | 5 +- .../keccak_f1600_x2_v8a_v84a_asm_hybrid.S | 6 +- ...ccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S | 6 +- ...eccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S | 6 +- ..._f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S | 5 +- fips202/native/api.h | 33 ++++++ fips202/native/default.h | 22 ++++ fips202/native/fips202_native.h | 81 -------------- fips202/native/x86_64/fips202_native_x86_64.h | 20 ---- .../KeccakP-1600-times4-SIMD256.c | 9 +- .../{xkcp => src}/KeccakP-1600-times4-SnP.h | 2 +- .../KeccakP-1600-unrolling.macros | 0 .../{xkcp => src}/KeccakP-SIMD256-config.h | 0 .../x86_64/{xkcp => src}/KeccakP-align.h | 0 .../x86_64/{xkcp => src}/KeccakP-brg_endian.h | 0 .../{profiles/xkcp.h => src/xkcp_impl.h} | 12 +-- fips202/native/x86_64/xkcp.h | 24 +++++ mk/crypto.mk | 2 +- mk/schemes.mk | 2 +- mlkem/api.h | 62 ----------- mlkem/arith_backend.h | 18 ++++ mlkem/cbd.c | 1 - mlkem/cbd.h | 2 +- mlkem/common.h | 70 +++--------- mlkem/config.h | 102 ++++++++++++++++++ mlkem/debug/debug.c | 1 - mlkem/debug/debug.h | 5 + mlkem/indcpa.c | 3 +- mlkem/indcpa.h | 3 +- mlkem/kem.c | 1 - mlkem/namespace.h | 57 ++++++++++ mlkem/native/aarch64/README.md | 2 +- mlkem/native/aarch64/clean.h | 24 +++++ mlkem/native/aarch64/opt.h | 24 +++++ .../native/aarch64/{ => src}/aarch64_zetas.c | 12 ++- .../aarch64/{ => src}/arith_native_aarch64.h | 10 +- .../{profiles/clean.h => src/clean_impl.h} | 11 +- mlkem/native/aarch64/{ => src}/common.i | 0 mlkem/native/aarch64/{ => src}/consts.h | 2 +- mlkem/native/aarch64/{ => src}/intt_clean.S | 6 +- mlkem/native/aarch64/{ => src}/intt_opt.S | 6 +- mlkem/native/aarch64/{ => src}/ntt_clean.S | 6 +- mlkem/native/aarch64/{ => src}/ntt_opt.S | 6 +- .../{profiles/opt.h => src/opt_impl.h} | 12 +-- mlkem/native/aarch64/{ => src}/optimize.sh | 0 mlkem/native/aarch64/{ => src}/poly_clean.S | 6 +- mlkem/native/aarch64/{ => src}/poly_opt.S | 6 +- .../native/aarch64/{ => src}/polyvec_clean.S | 6 +- mlkem/native/aarch64/{ => src}/polyvec_opt.S | 11 +- .../aarch64/{ => src}/rej_uniform_asm_clean.S | 9 +- mlkem/native/{arith_native.h => api.h} | 9 +- mlkem/native/default.h | 32 ++++++ mlkem/native/profile.h | 73 ------------- mlkem/native/x86_64/default.h | 24 +++++ mlkem/native/x86_64/{ => src}/align.h | 0 .../x86_64/{ => src}/arith_native_x86_64.h | 13 +-- mlkem/native/x86_64/{ => src}/basemul.S | 7 +- mlkem/native/x86_64/{ => src}/basemul.c | 12 +-- mlkem/native/x86_64/{ => src}/consts.c | 10 +- mlkem/native/x86_64/{ => src}/consts.h | 2 +- .../default.h => src/default_impl.h} | 11 +- mlkem/native/x86_64/{ => src}/fq.S | 9 +- mlkem/native/x86_64/{ => src}/fq.inc | 0 mlkem/native/x86_64/{ => src}/intt.S | 11 +- mlkem/native/x86_64/{ => src}/ntt.S | 9 +- .../x86_64/{ => src}/rej_uniform_avx2.c | 14 +-- mlkem/native/x86_64/{ => src}/shuffle.S | 10 +- mlkem/native/x86_64/{ => src}/shuffle.inc | 0 mlkem/native/x86_64/{ => src}/x86_64_zetas.i | 0 mlkem/ntt.c | 6 +- mlkem/ntt.h | 3 +- mlkem/params.h | 39 +------ mlkem/poly.c | 9 +- mlkem/poly.h | 2 +- mlkem/polyvec.c | 3 +- mlkem/polyvec.h | 2 +- mlkem/reduce.h | 2 +- mlkem/rej_uniform.c | 3 +- mlkem/rej_uniform.h | 2 +- mlkem/symmetric.h | 6 +- mlkem/{sys/cpucap.h => sys.h} | 57 +++++++++- mlkem/sys/config.h | 22 ---- mlkem/verify.c | 1 - scripts/autogenerate_files.py | 18 ++-- scripts/lib/mlkem_test.py | 4 +- test/bench_components_mlkem.c | 8 +- 105 files changed, 693 insertions(+), 636 deletions(-) delete mode 100644 examples/bring_your_own_fips202/custom_fips202/namespace.h create mode 100644 fips202/fips202_backend.h delete mode 100644 fips202/namespace.h create mode 100644 fips202/native/aarch64/cortex_a55.h create mode 100644 fips202/native/aarch64/default.h rename fips202/native/aarch64/{ => src}/common.i (100%) rename fips202/native/aarch64/{profiles/cortex_a55.h => src/cortex_a55_impl.h} (76%) rename fips202/native/aarch64/{profiles/default.h => src/default_impl.h} (95%) rename fips202/native/aarch64/{ => src}/fips202_native_aarch64.h (91%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x1_scalar_asm_opt.S (99%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x1_v84a_asm_clean.S (98%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x2_v84a_asm_clean.S (98%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x2_v8a_v84a_asm_hybrid.S (98%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S (99%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S (99%) rename fips202/native/aarch64/{ => src}/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S (99%) create mode 100644 fips202/native/api.h create mode 100644 fips202/native/default.h delete mode 100644 fips202/native/fips202_native.h delete mode 100644 fips202/native/x86_64/fips202_native_x86_64.h rename fips202/native/x86_64/{xkcp => src}/KeccakP-1600-times4-SIMD256.c (99%) rename fips202/native/x86_64/{xkcp => src}/KeccakP-1600-times4-SnP.h (97%) rename fips202/native/x86_64/{xkcp => src}/KeccakP-1600-unrolling.macros (100%) rename fips202/native/x86_64/{xkcp => src}/KeccakP-SIMD256-config.h (100%) rename fips202/native/x86_64/{xkcp => src}/KeccakP-align.h (100%) rename fips202/native/x86_64/{xkcp => src}/KeccakP-brg_endian.h (100%) rename fips202/native/x86_64/{profiles/xkcp.h => src/xkcp_impl.h} (60%) create mode 100644 fips202/native/x86_64/xkcp.h delete mode 100644 mlkem/api.h create mode 100644 mlkem/arith_backend.h create mode 100644 mlkem/config.h create mode 100644 mlkem/namespace.h create mode 100644 mlkem/native/aarch64/clean.h create mode 100644 mlkem/native/aarch64/opt.h rename mlkem/native/aarch64/{ => src}/aarch64_zetas.c (98%) rename mlkem/native/aarch64/{ => src}/arith_native_aarch64.h (96%) rename mlkem/native/aarch64/{profiles/clean.h => src/clean_impl.h} (90%) rename mlkem/native/aarch64/{ => src}/common.i (100%) rename mlkem/native/aarch64/{ => src}/consts.h (96%) rename mlkem/native/aarch64/{ => src}/intt_clean.S (98%) rename mlkem/native/aarch64/{ => src}/intt_opt.S (99%) rename mlkem/native/aarch64/{ => src}/ntt_clean.S (98%) rename mlkem/native/aarch64/{ => src}/ntt_opt.S (99%) rename mlkem/native/aarch64/{profiles/opt.h => src/opt_impl.h} (89%) rename mlkem/native/aarch64/{ => src}/optimize.sh (100%) rename mlkem/native/aarch64/{ => src}/poly_clean.S (98%) rename mlkem/native/aarch64/{ => src}/poly_opt.S (99%) rename mlkem/native/aarch64/{ => src}/polyvec_clean.S (98%) rename mlkem/native/aarch64/{ => src}/polyvec_opt.S (99%) rename mlkem/native/aarch64/{ => src}/rej_uniform_asm_clean.S (99%) rename mlkem/native/{arith_native.h => api.h} (98%) create mode 100644 mlkem/native/default.h delete mode 100644 mlkem/native/profile.h create mode 100644 mlkem/native/x86_64/default.h rename mlkem/native/x86_64/{ => src}/align.h (100%) rename mlkem/native/x86_64/{ => src}/arith_native_x86_64.h (91%) rename mlkem/native/x86_64/{ => src}/basemul.S (96%) rename mlkem/native/x86_64/{ => src}/basemul.c (90%) rename mlkem/native/x86_64/{ => src}/consts.c (92%) rename mlkem/native/x86_64/{ => src}/consts.h (97%) rename mlkem/native/x86_64/{profiles/default.h => src/default_impl.h} (92%) rename mlkem/native/x86_64/{ => src}/fq.S (91%) rename mlkem/native/x86_64/{ => src}/fq.inc (100%) rename mlkem/native/x86_64/{ => src}/intt.S (97%) rename mlkem/native/x86_64/{ => src}/ntt.S (97%) rename mlkem/native/x86_64/{ => src}/rej_uniform_avx2.c (98%) rename mlkem/native/x86_64/{ => src}/shuffle.S (96%) rename mlkem/native/x86_64/{ => src}/shuffle.inc (100%) rename mlkem/native/x86_64/{ => src}/x86_64_zetas.i (100%) rename mlkem/{sys/cpucap.h => sys.h} (53%) delete mode 100644 mlkem/sys/config.h diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 5aa9a53c8..4dd9c7b12 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -43,7 +43,7 @@ jobs: name: Arm Cortex-A55 (Snapdragon 888) benchmarks bench_pmu: PERF archflags: "-mcpu=cortex-a55 -march=armv8.2-a" - cflags: "-flto -static -DFORCE_AARCH64 -DFIPS202_NATIVE_PROFILE=\"aarch64/profiles/cortex_a55.h\"" + cflags: "-flto -static -DFORCE_AARCH64 -DMLKEM_NATIVE_FIPS202_BACKEND=\\\\\\\"aarch64/cortex_a55.h\\\\\\\"" bench_extra_args: -w exec-on-a55 - system: bpi name: Bananapi bpi-f3 benchmarks diff --git a/examples/bring_your_own_fips202/Makefile b/examples/bring_your_own_fips202/Makefile index 1a80951e9..e4152b7b0 100644 --- a/examples/bring_your_own_fips202/Makefile +++ b/examples/bring_your_own_fips202/Makefile @@ -19,7 +19,6 @@ INC= INC+=-Imlkem_native/mlkem INC+=-Imlkem_native/mlkem INC+=-Imlkem_native/mlkem/native -INC+=-Imlkem_native/mlkem/sys # Part B: # diff --git a/examples/bring_your_own_fips202/custom_fips202/fips202.h b/examples/bring_your_own_fips202/custom_fips202/fips202.h index 5ffe60fae..4bebebeb0 100644 --- a/examples/bring_your_own_fips202/custom_fips202/fips202.h +++ b/examples/bring_your_own_fips202/custom_fips202/fips202.h @@ -11,7 +11,7 @@ #ifndef FIPS202_H #define FIPS202_H -#include "namespace.h" +#include "common.h" #include "tiny_sha3/sha3.h" #define SHAKE128_RATE 168 diff --git a/examples/bring_your_own_fips202/custom_fips202/namespace.h b/examples/bring_your_own_fips202/custom_fips202/namespace.h deleted file mode 100644 index fab249afa..000000000 --- a/examples/bring_your_own_fips202/custom_fips202/namespace.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef NAMESPACE_H -#define NAMESPACE_H - -#include "config.h" - -#if defined(MLKEM_USE_NATIVE_X86_64) -#define MLKEM_NATIVE_BACKEND X86_64 -#elif defined(MLKEM_USE_NATIVE_AARCH64) -#define MLKEM_NATIVE_BACKEND AARCH64 -#else -#define MLKEM_NATIVE_BACKEND C -#endif - -#define ___FIPS202_NAMESPACE(x1, x2, x3) x1##_##x2##_##x3 -#define __FIPS202_NAMESPACE(x1, x2, x3) ___FIPS202_NAMESPACE(x1, x2, x3) - -/* - * NAMESPACE is PQCP_MLKEM_NATIVE_FIPS202__ - * e.g., PQCP_MLKEM_NATIVE_FIPS202_AARCH64_ - */ -#define FIPS202_NAMESPACE(s) \ - __FIPS202_NAMESPACE(PQCP_MLKEM_NATIVE_FIPS202, MLKEM_NATIVE_BACKEND, s) -#define _FIPS202_NAMESPACE(s) \ - __FIPS202_NAMESPACE(_PQCP_MLKEM_NATIVE_FIPS202, MLKEM_NATIVE_BACKEND, s) - -#endif diff --git a/examples/mlkem_native_as_code_package/Makefile b/examples/mlkem_native_as_code_package/Makefile index 1a6aed46a..127afd7d2 100644 --- a/examples/mlkem_native_as_code_package/Makefile +++ b/examples/mlkem_native_as_code_package/Makefile @@ -21,7 +21,6 @@ INC+=-Imlkem_native/mlkem INC+=-Imlkem_native/mlkem/native INC+=-Imlkem_native/fips202 INC+=-Imlkem_native/fips202/native -INC+=-Imlkem_native/mlkem/sys # Part B: # diff --git a/fips202/fips202.h b/fips202/fips202.h index 48429c271..333a959d7 100644 --- a/fips202/fips202.h +++ b/fips202/fips202.h @@ -7,9 +7,8 @@ #include #include -#include "namespace.h" - #include "cbmc.h" +#include "common.h" #define SHAKE128_RATE 168 #define SHAKE256_RATE 136 diff --git a/fips202/fips202_backend.h b/fips202/fips202_backend.h new file mode 100644 index 000000000..24e6593b2 --- /dev/null +++ b/fips202/fips202_backend.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef MLKEM_NATIVE_FIPS202_IMPL_H +#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? +#else +#define MLKEM_NATIVE_FIPS202_IMPL_H + +/* Include to enforce consistency of API and implementation */ +#include "native/api.h" + +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_IMPL) +#include MLKEM_NATIVE_FIPS202_BACKEND_IMPL +#endif + +#endif /* MLKEM_NATIVE_FIPS202_IMPL_H */ diff --git a/fips202/fips202x4.h b/fips202/fips202x4.h index 33a732a88..1bb0d08c7 100644 --- a/fips202/fips202x4.h +++ b/fips202/fips202x4.h @@ -7,9 +7,9 @@ #include #include +#include "common.h" #include "fips202.h" #include "keccakf1600.h" -#include "namespace.h" #include "cbmc.h" diff --git a/fips202/keccakf1600.c b/fips202/keccakf1600.c index 7b653fca9..5049999dd 100644 --- a/fips202/keccakf1600.c +++ b/fips202/keccakf1600.c @@ -15,7 +15,7 @@ #include #include "config.h" -#include "fips202_native.h" +#include "fips202_backend.h" #include "cbmc.h" diff --git a/fips202/keccakf1600.h b/fips202/keccakf1600.h index 7341df0bf..3d59e0b19 100644 --- a/fips202/keccakf1600.h +++ b/fips202/keccakf1600.h @@ -6,10 +6,8 @@ #define KECCAKF1600_H #include -#include "fips202_native.h" -#include "namespace.h" - #include "cbmc.h" +#include "common.h" #define KECCAK_LANES 25 /* diff --git a/fips202/namespace.h b/fips202/namespace.h deleted file mode 100644 index fab249afa..000000000 --- a/fips202/namespace.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef NAMESPACE_H -#define NAMESPACE_H - -#include "config.h" - -#if defined(MLKEM_USE_NATIVE_X86_64) -#define MLKEM_NATIVE_BACKEND X86_64 -#elif defined(MLKEM_USE_NATIVE_AARCH64) -#define MLKEM_NATIVE_BACKEND AARCH64 -#else -#define MLKEM_NATIVE_BACKEND C -#endif - -#define ___FIPS202_NAMESPACE(x1, x2, x3) x1##_##x2##_##x3 -#define __FIPS202_NAMESPACE(x1, x2, x3) ___FIPS202_NAMESPACE(x1, x2, x3) - -/* - * NAMESPACE is PQCP_MLKEM_NATIVE_FIPS202__ - * e.g., PQCP_MLKEM_NATIVE_FIPS202_AARCH64_ - */ -#define FIPS202_NAMESPACE(s) \ - __FIPS202_NAMESPACE(PQCP_MLKEM_NATIVE_FIPS202, MLKEM_NATIVE_BACKEND, s) -#define _FIPS202_NAMESPACE(s) \ - __FIPS202_NAMESPACE(_PQCP_MLKEM_NATIVE_FIPS202, MLKEM_NATIVE_BACKEND, s) - -#endif diff --git a/fips202/native/aarch64/cortex_a55.h b/fips202/native/aarch64/cortex_a55.h new file mode 100644 index 000000000..3d9d92879 --- /dev/null +++ b/fips202/native/aarch64/cortex_a55.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* FIPS202 assembly profile targeting Cortex-A55 */ + +#ifdef FIPS202_NATIVE_PROFILE_H +#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? +#else +#define FIPS202_NATIVE_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55 + +#define MLKEM_NATIVE_FIPS202_BACKEND_NAME AARCH64_A55 + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_IMPL "aarch64/src/cortex_a55_impl.h" + +#endif /* FIPS202_NATIVE_PROFILE_H */ diff --git a/fips202/native/aarch64/default.h b/fips202/native/aarch64/default.h new file mode 100644 index 000000000..1386c6440 --- /dev/null +++ b/fips202/native/aarch64/default.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default FIPS202 assembly profile for AArch64 systems */ + +#ifdef FIPS202_NATIVE_PROFILE_H +#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? +#else +#define FIPS202_NATIVE_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT + +#define MLKEM_NATIVE_FIPS202_BACKEND_NAME AARCH64_DEFAULT + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_IMPL "aarch64/src/default_impl.h" + +#endif /* FIPS202_NATIVE_PROFILE_H */ diff --git a/fips202/native/aarch64/common.i b/fips202/native/aarch64/src/common.i similarity index 100% rename from fips202/native/aarch64/common.i rename to fips202/native/aarch64/src/common.i diff --git a/fips202/native/aarch64/profiles/cortex_a55.h b/fips202/native/aarch64/src/cortex_a55_impl.h similarity index 76% rename from fips202/native/aarch64/profiles/cortex_a55.h rename to fips202/native/aarch64/src/cortex_a55_impl.h index 3ca536bf4..90b857f66 100644 --- a/fips202/native/aarch64/profiles/cortex_a55.h +++ b/fips202/native/aarch64/src/cortex_a55_impl.h @@ -5,12 +5,12 @@ /* FIPS202 assembly profile targeting Cortex-A55 */ -#ifdef FIPS202_NATIVE_PROFILE_H +#ifdef FIPS202_NATIVE_PROFILE_IMPL_H #error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? #else -#define FIPS202_NATIVE_PROFILE_H +#define FIPS202_NATIVE_PROFILE_IMPL_H -#include "../fips202_native_aarch64.h" +#include "fips202_native_aarch64.h" /* * On Cortex-A55, we use lazy rotation assembly for Keccak-x1, @@ -22,4 +22,4 @@ static INLINE void keccak_f1600_x1_native(uint64_t *state) keccak_f1600_x1_scalar_asm_opt(state); } -#endif /* FIPS202_NATIVE_PROFILE_H */ +#endif /* FIPS202_NATIVE_PROFILE_IMPL_H */ diff --git a/fips202/native/aarch64/profiles/default.h b/fips202/native/aarch64/src/default_impl.h similarity index 95% rename from fips202/native/aarch64/profiles/default.h rename to fips202/native/aarch64/src/default_impl.h index 3a9da28b7..4d28e35bf 100644 --- a/fips202/native/aarch64/profiles/default.h +++ b/fips202/native/aarch64/src/default_impl.h @@ -5,12 +5,12 @@ /* Default FIPS202 assembly profile for AArch64 systems */ -#ifdef FIPS202_NATIVE_PROFILE_H +#ifdef FIPS202_NATIVE_PROFILE_IMPL_H #error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? #else -#define FIPS202_NATIVE_PROFILE_H +#define FIPS202_NATIVE_PROFILE_IMPL_H -#include "../fips202_native_aarch64.h" +#include "fips202_native_aarch64.h" /* * Default logic to decide which implementation to use. diff --git a/fips202/native/aarch64/fips202_native_aarch64.h b/fips202/native/aarch64/src/fips202_native_aarch64.h similarity index 91% rename from fips202/native/aarch64/fips202_native_aarch64.h rename to fips202/native/aarch64/src/fips202_native_aarch64.h index 72e7c9710..d62b2c958 100644 --- a/fips202/native/aarch64/fips202_native_aarch64.h +++ b/fips202/native/aarch64/src/fips202_native_aarch64.h @@ -6,11 +6,8 @@ #define FIPS202_AARCH64_NATIVE_H #include -#include "config.h" -#include "namespace.h" -#include "params.h" +#include "common.h" -#ifdef MLKEM_USE_NATIVE_AARCH64 #define keccak_f1600_x1_scalar_asm_opt \ FIPS202_NAMESPACE(keccak_f1600_x1_scalar_asm_opt) void keccak_f1600_x1_scalar_asm_opt(uint64_t *state); @@ -38,6 +35,5 @@ void keccak_f1600_x4_scalar_v84a_asm_hybrid_opt(uint64_t *state); #define keccak_f1600_x4_scalar_v8a_v84a_hybrid_asm_opt \ FIPS202_NAMESPACE(keccak_f1600_x4_scalar_v8a_v84a_hybrid_asm_opt) void keccak_f1600_x4_scalar_v8a_v84a_hybrid_asm_opt(uint64_t *state); -#endif /* MLKEM_USE_NATIVE_AARCH64 */ #endif /* FIPS202_AARCH64_NATIVE_H */ diff --git a/fips202/native/aarch64/keccak_f1600_x1_scalar_asm_opt.S b/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm_opt.S similarity index 99% rename from fips202/native/aarch64/keccak_f1600_x1_scalar_asm_opt.S rename to fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm_opt.S index 3db9e2046..3655a219d 100644 --- a/fips202/native/aarch64/keccak_f1600_x1_scalar_asm_opt.S +++ b/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm_opt.S @@ -28,12 +28,12 @@ // Author: Hanno Becker // Author: Matthias Kannwischer -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" -#include "namespace.h" /********************** CONSTANTS *************************/ .data @@ -457,4 +457,5 @@ initial: free_stack ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) */ diff --git a/fips202/native/aarch64/keccak_f1600_x1_v84a_asm_clean.S b/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm_clean.S similarity index 98% rename from fips202/native/aarch64/keccak_f1600_x1_v84a_asm_clean.S rename to fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm_clean.S index 0613a8a75..c60e4cad4 100644 --- a/fips202/native/aarch64/keccak_f1600_x1_v84a_asm_clean.S +++ b/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm_clean.S @@ -37,8 +37,9 @@ // during load and store, so that the caller need not do this. // -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" diff --git a/fips202/native/aarch64/keccak_f1600_x2_v84a_asm_clean.S b/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm_clean.S similarity index 98% rename from fips202/native/aarch64/keccak_f1600_x2_v84a_asm_clean.S rename to fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm_clean.S index f74856a5f..45304aa25 100644 --- a/fips202/native/aarch64/keccak_f1600_x2_v84a_asm_clean.S +++ b/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm_clean.S @@ -37,8 +37,9 @@ // during load and store, so that the caller need not do this. // -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" diff --git a/fips202/native/aarch64/keccak_f1600_x2_v8a_v84a_asm_hybrid.S b/fips202/native/aarch64/src/keccak_f1600_x2_v8a_v84a_asm_hybrid.S similarity index 98% rename from fips202/native/aarch64/keccak_f1600_x2_v8a_v84a_asm_hybrid.S rename to fips202/native/aarch64/src/keccak_f1600_x2_v8a_v84a_asm_hybrid.S index b7cc6f261..e4fecb11d 100644 --- a/fips202/native/aarch64/keccak_f1600_x2_v8a_v84a_asm_hybrid.S +++ b/fips202/native/aarch64/src/keccak_f1600_x2_v8a_v84a_asm_hybrid.S @@ -37,12 +37,12 @@ // during load and store, so that the caller need not do this. // -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" -#include "namespace.h" #if defined(__ARM_FEATURE_SHA3) diff --git a/fips202/native/aarch64/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S b/fips202/native/aarch64/src/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S similarity index 99% rename from fips202/native/aarch64/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S rename to fips202/native/aarch64/src/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S index 19a93b9e8..abf1af497 100644 --- a/fips202/native/aarch64/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S +++ b/fips202/native/aarch64/src/keccak_f1600_x4_scalar_v84a_asm_hybrid_opt.S @@ -24,12 +24,12 @@ * */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" -#include "namespace.h" #if defined(__ARM_FEATURE_SHA3) diff --git a/fips202/native/aarch64/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S b/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S similarity index 99% rename from fips202/native/aarch64/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S rename to fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S index a32375f07..f001d3eaf 100644 --- a/fips202/native/aarch64/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S +++ b/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm_opt.S @@ -24,12 +24,12 @@ * */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" -#include "namespace.h" #define KECCAK_F1600_ROUNDS 24 diff --git a/fips202/native/aarch64/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S b/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S similarity index 99% rename from fips202/native/aarch64/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S rename to fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S index 889ba2983..67a0adccd 100644 --- a/fips202/native/aarch64/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S +++ b/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm_opt.S @@ -24,8 +24,9 @@ * */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_DEFAULT) || \ + defined(MLKEM_NATIVE_FIPS202_BACKEND_AARCH64_A55) // Needed to provide ASM_LOAD directive #include "common.i" diff --git a/fips202/native/api.h b/fips202/native/api.h new file mode 100644 index 000000000..685b8bfc5 --- /dev/null +++ b/fips202/native/api.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef FIPS202_NATIVE_H +#define FIPS202_NATIVE_H + +#include +#include "common.h" + +/* + * FIPS202 native interface + */ + +/* + * Those functions are meant to be trivial wrappers around + * the chosen native implementation. The are static inline + * to avoid unnecessary calls. + * The macro before each declaration controls whether a native + * implementation is present. + */ + +#if defined(MLKEM_USE_FIPS202_X1_NATIVE) +static INLINE void keccak_f1600_x1_native(uint64_t *state); +#endif +#if defined(MLKEM_USE_FIPS202_X2_NATIVE) +static INLINE void keccak_f1600_x2_native(uint64_t *state); +#endif +#if defined(MLKEM_USE_FIPS202_X4_NATIVE) +static INLINE void keccak_f1600_x4_native(uint64_t *state); +#endif + +#endif /* FIPS202_NATIVE_H */ diff --git a/fips202/native/default.h b/fips202/native/default.h new file mode 100644 index 000000000..41c068910 --- /dev/null +++ b/fips202/native/default.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef MLKEM_NATIVE_FIPS202_BACKEND_DEFAULT_H +#define MLKEM_NATIVE_FIPS202_BACKEND_DEFAULT_H + +/* + * Default FIPS202 backend + */ +#include "sys.h" + +#if defined(SYS_AARCH64) +#include "aarch64/default.h" +#endif + +#if defined(SYS_X86_64) && defined(SYS_X86_64_AVX2) +#include "x86_64/xkcp.h" +#endif + +#endif /* MLKEM_NATIVE_FIPS202_BACKEND_DEFAULT_H */ diff --git a/fips202/native/fips202_native.h b/fips202/native/fips202_native.h deleted file mode 100644 index ccddc32a9..000000000 --- a/fips202/native/fips202_native.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef FIPS202_NATIVE_H -#define FIPS202_NATIVE_H - -#include -#include "config.h" -#include "params.h" - -#if defined(MLKEM_USE_NATIVE) - -/* - * FIPS202 native profile - * - * The profile decides which implementation(s) of FIPS202 to use. - * - * If you don't change anything, the default profile will be used. This profile - * picks implementations based on characteristics of your system visible to - * the compiler. - * - * The default logic is not perfect, and you may want to pick a specific - * profile for your target. There are three ways to do so, in descending - * order of convenience to the user: - * 1. Pick one of the profiles shipped with this repository. - * 2. Provide your own profile and register it via FIPS202_ASM_PROFILE - * (which must be the profile's path relative to this directoru). - * 3. Set FIPS202_NATIVE_MANUAL and use an adhoc profile specified via CFLAGS. - */ - -/* Option 2: Manually written profile */ -#if defined(FIPS202_NATIVE_PROFILE) - -#define STRINGIFY_(x) #x -#define STRINGIFY(x) STRINGIFY_(x) -#include STRINGIFY(FIPS202_NATIVE_PROFILE) - -/* Option 1: Choose from shipped list of profiles */ -#elif !defined(FIPS202_NATIVE_MANUAL) - -#ifdef SYS_AARCH64 -/* Pick exactly one profile from the following list */ -#include "aarch64/profiles/default.h" -/* #include "aarch64/profiles/cortex_a55.h" */ -#endif - -#if defined(SYS_X86_64) && defined(SYS_X86_64_AVX2) -#include "x86_64/profiles/xkcp.h" -#endif - -#else /* !FIPS202_NATIVE_PROFILE && FIPS202_NATIVE_MANUAL */ - -/* Option 3: Build your own profile here, or via CFLAGS */ - -#endif /* !FIPS202_NATIVE_PROFILE && !FIPS202_NATIVE_MANUAL */ - -/* - * FIPS202 native interface - */ - -/* - * Those functions are meant to be trivial wrappers around - * the chosen native implementation. The are static inline - * to avoid unnecessary calls. - * The macro before each declaration controls whether a native - * implementation is present. - */ - -#if defined(MLKEM_USE_FIPS202_X1_NATIVE) -static INLINE void keccak_f1600_x1_native(uint64_t *state); -#endif -#if defined(MLKEM_USE_FIPS202_X2_NATIVE) -static INLINE void keccak_f1600_x2_native(uint64_t *state); -#endif -#if defined(MLKEM_USE_FIPS202_X4_NATIVE) -static INLINE void keccak_f1600_x4_native(uint64_t *state); -#endif - -#endif /* MLKEM_USE_NATIVE */ -#endif /* FIPS202_NATIVE_H */ diff --git a/fips202/native/x86_64/fips202_native_x86_64.h b/fips202/native/x86_64/fips202_native_x86_64.h deleted file mode 100644 index cbc0bb97d..000000000 --- a/fips202/native/x86_64/fips202_native_x86_64.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef FIPS202_X86_64_NATIVE_H -#define FIPS202_X86_64_NATIVE_H - -#include "config.h" - -#ifdef MLKEM_USE_NATIVE_X86_64 - -#include -#include -#include - -#include "xkcp/KeccakP-1600-times4-SnP.h" - -#endif /* MLKEM_USE_NATIVE_X86_64 */ - -#endif /* FIPS202_X86_64_NATIVE_H */ diff --git a/fips202/native/x86_64/xkcp/KeccakP-1600-times4-SIMD256.c b/fips202/native/x86_64/src/KeccakP-1600-times4-SIMD256.c similarity index 99% rename from fips202/native/x86_64/xkcp/KeccakP-1600-times4-SIMD256.c rename to fips202/native/x86_64/src/KeccakP-1600-times4-SIMD256.c index 9a36f17aa..d56823ab3 100644 --- a/fips202/native/x86_64/xkcp/KeccakP-1600-times4-SIMD256.c +++ b/fips202/native/x86_64/src/KeccakP-1600-times4-SIMD256.c @@ -24,8 +24,8 @@ and related or neighboring rights to the source code in this file. * Keccak states in memory. */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#include "common.h" +#if defined(MLKEM_NATIVE_FIPS202_BACKEND_X86_64_XKCP) #include #include @@ -445,10 +445,9 @@ void KeccakP1600times4_PermuteAll_24rounds(void *states) } #else -#include "params.h" /* Dummy constant to keep compiler happy despite empty CU */ -#define empty_cu_avx2_keccakx4 MLKEM_NAMESPACE(empty_cu_avx2_keccakx4) +#define empty_cu_avx2_keccakx4 FIPS202_NAMESPACE(empty_cu_avx2_keccakx4) int empty_cu_avx2_keccakx4; -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_FIPS202_BACKEND_X86_64_XKCP */ diff --git a/fips202/native/x86_64/xkcp/KeccakP-1600-times4-SnP.h b/fips202/native/x86_64/src/KeccakP-1600-times4-SnP.h similarity index 97% rename from fips202/native/x86_64/xkcp/KeccakP-1600-times4-SnP.h rename to fips202/native/x86_64/src/KeccakP-1600-times4-SnP.h index 6d1951787..0738c9488 100644 --- a/fips202/native/x86_64/xkcp/KeccakP-1600-times4-SnP.h +++ b/fips202/native/x86_64/src/KeccakP-1600-times4-SnP.h @@ -26,7 +26,7 @@ and related or neighboring rights to the source code in this file. #include #include "KeccakP-SIMD256-config.h" -#include "namespace.h" +#include "common.h" #define KeccakP1600times4_statesAlignment 32 diff --git a/fips202/native/x86_64/xkcp/KeccakP-1600-unrolling.macros b/fips202/native/x86_64/src/KeccakP-1600-unrolling.macros similarity index 100% rename from fips202/native/x86_64/xkcp/KeccakP-1600-unrolling.macros rename to fips202/native/x86_64/src/KeccakP-1600-unrolling.macros diff --git a/fips202/native/x86_64/xkcp/KeccakP-SIMD256-config.h b/fips202/native/x86_64/src/KeccakP-SIMD256-config.h similarity index 100% rename from fips202/native/x86_64/xkcp/KeccakP-SIMD256-config.h rename to fips202/native/x86_64/src/KeccakP-SIMD256-config.h diff --git a/fips202/native/x86_64/xkcp/KeccakP-align.h b/fips202/native/x86_64/src/KeccakP-align.h similarity index 100% rename from fips202/native/x86_64/xkcp/KeccakP-align.h rename to fips202/native/x86_64/src/KeccakP-align.h diff --git a/fips202/native/x86_64/xkcp/KeccakP-brg_endian.h b/fips202/native/x86_64/src/KeccakP-brg_endian.h similarity index 100% rename from fips202/native/x86_64/xkcp/KeccakP-brg_endian.h rename to fips202/native/x86_64/src/KeccakP-brg_endian.h diff --git a/fips202/native/x86_64/profiles/xkcp.h b/fips202/native/x86_64/src/xkcp_impl.h similarity index 60% rename from fips202/native/x86_64/profiles/xkcp.h rename to fips202/native/x86_64/src/xkcp_impl.h index 4f320e994..c0ad76850 100644 --- a/fips202/native/x86_64/profiles/xkcp.h +++ b/fips202/native/x86_64/src/xkcp_impl.h @@ -5,14 +5,12 @@ /* Default FIPS202 assembly profile for AArch64 systems */ -#ifdef FIPS202_NATIVE_PROFILE_H +#ifdef MLKEM_NATIVE_FIPS202_PROFILE_IMPL_H #error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? #else -#define FIPS202_NATIVE_PROFILE_H +#define MLKEM_NATIVE_FIPS202_PROFILE_IMPL_H -#include "../fips202_native_x86_64.h" - -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#include "KeccakP-1600-times4-SnP.h" #define MLKEM_USE_FIPS202_X4_NATIVE static INLINE void keccak_f1600_x4_native(uint64_t *state) @@ -20,6 +18,4 @@ static INLINE void keccak_f1600_x4_native(uint64_t *state) KeccakP1600times4_PermuteAll_24rounds(state); } -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ - -#endif /* FIPS202_NATIVE_PROFILE_H */ +#endif /* MLKEM_NATIVE_FIPS202_PROFILE_IMPL_H */ diff --git a/fips202/native/x86_64/xkcp.h b/fips202/native/x86_64/xkcp.h new file mode 100644 index 000000000..1cfcee9fd --- /dev/null +++ b/fips202/native/x86_64/xkcp.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default FIPS202 assembly profile for AArch64 systems */ + +#ifdef MLKEM_NATIVE_FIPS202_PROFILE_H +#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? +#else +#define MLKEM_NATIVE_FIPS202_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_X86_64_XKCP + +#define MLKEM_NATIVE_FIPS202_BACKEND_NAME X86_64_XKCP + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_IMPL "x86_64/src/xkcp_impl.h" + +#endif /* MLKEM_NATIVE_FIPS202_PROFILE_H */ diff --git a/mk/crypto.mk b/mk/crypto.mk index faf0eb047..9cb04227d 100644 --- a/mk/crypto.mk +++ b/mk/crypto.mk @@ -2,7 +2,7 @@ CPPFLAGS += -Ifips202 -Ifips202/native FIPS202_SRCS = $(wildcard fips202/*.c) ifeq ($(OPT),1) - FIPS202_SRCS += $(wildcard fips202/native/aarch64/*.S) $(wildcard fips202/native/x86_64/xkcp/*.c) + FIPS202_SRCS += $(wildcard fips202/native/aarch64/src/*.S) $(wildcard fips202/native/x86_64/src/*.c) endif $(BUILD_DIR)/libmlkem.a: $(call OBJS, $(FIPS202_SRCS)) diff --git a/mk/schemes.mk b/mk/schemes.mk index deabcdd86..ede00a635 100644 --- a/mk/schemes.mk +++ b/mk/schemes.mk @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 SOURCES += $(wildcard mlkem/*.c) $(wildcard mlkem/debug/*.c) ifeq ($(OPT),1) - SOURCES += $(wildcard mlkem/native/aarch64/*.[csS]) $(wildcard mlkem/native/x86_64/*.[csS]) + SOURCES += $(wildcard mlkem/native/aarch64/src/*.[csS]) $(wildcard mlkem/native/x86_64/src/*.[csS]) CPPFLAGS += -DMLKEM_USE_NATIVE endif diff --git a/mlkem/api.h b/mlkem/api.h deleted file mode 100644 index 94597323f..000000000 --- a/mlkem/api.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef API_H -#define API_H - -#include - -#define PQCP_MLKEM_NATIVE_MLKEM512_SECRETKEYBYTES 1632 -#define PQCP_MLKEM_NATIVE_MLKEM512_PUBLICKEYBYTES 800 -#define PQCP_MLKEM_NATIVE_MLKEM512_CIPHERTEXTBYTES 768 -#define PQCP_MLKEM_NATIVE_MLKEM512_KEYPAIRCOINBYTES 64 -#define PQCP_MLKEM_NATIVE_MLKEM512_ENCCOINBYTES 32 -#define PQCP_MLKEM_NATIVE_MLKEM512_BYTES 32 - -int PQCP_MLKEM_NATIVE_MLKEM512_keypair_derand(uint8_t *pk, uint8_t *sk, - const uint8_t *coins); -int PQCP_MLKEM_NATIVE_MLKEM512_keypair(uint8_t *pk, uint8_t *sk); -int PQCP_MLKEM_NATIVE_MLKEM512_enc_derand(uint8_t *ct, uint8_t *ss, - const uint8_t *pk, - const uint8_t *coins); -int PQCP_MLKEM_NATIVE_MLKEM512_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCP_MLKEM_NATIVE_MLKEM512_dec(uint8_t *ss, const uint8_t *ct, - const uint8_t *sk); - -#define PQCP_MLKEM_NATIVE_MLKEM768_SECRETKEYBYTES 2400 -#define PQCP_MLKEM_NATIVE_MLKEM768_PUBLICKEYBYTES 1184 -#define PQCP_MLKEM_NATIVE_MLKEM768_CIPHERTEXTBYTES 1088 -#define PQCP_MLKEM_NATIVE_MLKEM768_KEYPAIRCOINBYTES 64 -#define PQCP_MLKEM_NATIVE_MLKEM768_ENCCOINBYTES 32 -#define PQCP_MLKEM_NATIVE_MLKEM768_BYTES 32 - -int PQCP_MLKEM_NATIVE_MLKEM768_keypair_derand(uint8_t *pk, uint8_t *sk, - const uint8_t *coins); -int PQCP_MLKEM_NATIVE_MLKEM768_keypair(uint8_t *pk, uint8_t *sk); -int PQCP_MLKEM_NATIVE_MLKEM768_enc_derand(uint8_t *ct, uint8_t *ss, - const uint8_t *pk, - const uint8_t *coins); -int PQCP_MLKEM_NATIVE_MLKEM768_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCP_MLKEM_NATIVE_MLKEM768_dec(uint8_t *ss, const uint8_t *ct, - const uint8_t *sk); - -#define PQCP_MLKEM_NATIVE_MLKEM1024_SECRETKEYBYTES 3168 -#define PQCP_MLKEM_NATIVE_MLKEM1024_PUBLICKEYBYTES 1568 -#define PQCP_MLKEM_NATIVE_MLKEM1024_CIPHERTEXTBYTES 1568 -#define PQCP_MLKEM_NATIVE_MLKEM1024_KEYPAIRCOINBYTES 64 -#define PQCP_MLKEM_NATIVE_MLKEM1024_ENCCOINBYTES 32 -#define PQCP_MLKEM_NATIVE_MLKEM1024_BYTES 32 - -int PQCP_MLKEM_NATIVE_MLKEM1024_keypair_derand(uint8_t *pk, uint8_t *sk, - const uint8_t *coins); -int PQCP_MLKEM_NATIVE_MLKEM1024_keypair(uint8_t *pk, uint8_t *sk); -int PQCP_MLKEM_NATIVE_MLKEM1024_enc_derand(uint8_t *ct, uint8_t *ss, - const uint8_t *pk, - const uint8_t *coins); -int PQCP_MLKEM_NATIVE_MLKEM1024_enc(uint8_t *ct, uint8_t *ss, - const uint8_t *pk); -int PQCP_MLKEM_NATIVE_MLKEM1024_dec(uint8_t *ss, const uint8_t *ct, - const uint8_t *sk); - -#endif diff --git a/mlkem/arith_backend.h b/mlkem/arith_backend.h new file mode 100644 index 000000000..7fb3df84d --- /dev/null +++ b/mlkem/arith_backend.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef MLKEM_NATIVE_ARITH_IMPL_H +#error Only one ARITH assembly profile can be defined -- did you include multiple profiles? +#else +#define MLKEM_NATIVE_ARITH_IMPL_H + +/* Include to enforce consistency of API and implementation */ +#include "native/api.h" + +#if defined(MLKEM_NATIVE_ARITH_BACKEND_IMPL) +#include MLKEM_NATIVE_ARITH_BACKEND_IMPL +#endif + +#endif /* MLKEM_NATIVE_ARITH_IMPL_H */ diff --git a/mlkem/cbd.c b/mlkem/cbd.c index 073f3c81d..2e0fac38a 100644 --- a/mlkem/cbd.c +++ b/mlkem/cbd.c @@ -4,7 +4,6 @@ */ #include "cbd.h" #include -#include "params.h" /************************************************* * Name: load32_littleendian diff --git a/mlkem/cbd.h b/mlkem/cbd.h index 4dc8635bb..31c9649e3 100644 --- a/mlkem/cbd.h +++ b/mlkem/cbd.h @@ -6,7 +6,7 @@ #define CBD_H #include -#include "params.h" +#include "common.h" #include "poly.h" #define poly_cbd_eta1 MLKEM_NAMESPACE(poly_cbd_eta1) diff --git a/mlkem/common.h b/mlkem/common.h index 94c29ed92..3469d2739 100644 --- a/mlkem/common.h +++ b/mlkem/common.h @@ -2,64 +2,28 @@ * Copyright (c) 2024 The mlkem-native project authors * SPDX-License-Identifier: Apache-2.0 */ -#ifndef COMMON_H -#define COMMON_H +#ifndef MLKEM_NATIVE_COMMON_H +#define MLKEM_NATIVE_COMMON_H +#if defined(MLKEM_NATIVE_CONFIG_FILE) +#include MLKEM_NATIVE_CONFIG_FILE +#endif /* MLKEM_NATIVE_CONFIG_FILE */ -/* - * C90 does not have the inline compiler directive yet. - * We don't use it in C90 builds. - * However, in that case the compiler warns about some inline functions in - * header files not being used in every compilation unit that includes that - * header. To work around it we silence that warning in that case using - * __attribute__((unused)). - */ +#include "params.h" +#include "sys.h" -/* Do not use inline for C90 builds*/ -#if !defined(inline) -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#define INLINE inline -#define ALWAYS_INLINE __attribute__((always_inline)) -#elif defined(_MSC_VER) -#define INLINE __inline -#define ALWAYS_INLINE __forceinline -#else -#define INLINE __attribute__((unused)) -#define ALWAYS_INLINE +/* Include backend metadata */ +#if defined(MLKEM_USE_NATIVE) +#if defined(MLKEM_NATIVE_ARITH_BACKEND) +#include MLKEM_NATIVE_ARITH_BACKEND #endif - -#else -#define INLINE inline -#define ALWAYS_INLINE __attribute__((always_inline)) +#if defined(MLKEM_NATIVE_FIPS202_BACKEND) +#include MLKEM_NATIVE_FIPS202_BACKEND #endif - - -/* - * C90 does not have the restrict compiler directive yet. - * We don't use it in C90 builds. - */ -#if !defined(restrict) -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#define RESTRICT restrict -#else -#define RESTRICT #endif -#else +/* This must come after the inclusion of the backend metadata + * since the backend choice may be part of the namespace. */ +#include "namespace.h" -#define RESTRICT restrict -#endif - -#define DEFAULT_ALIGN 32 -#if defined(_WIN32) -#define ALIGN __declspec(align(DEFAULT_ALIGN)) -#define asm __asm -#else -#define asm __asm__ -#define ALIGN __attribute__((aligned(DEFAULT_ALIGN))) -#endif - -#define MLKEM_CONCAT_(left, right) left##right -#define MLKEM_CONCAT(left, right) MLKEM_CONCAT_(left, right) - -#endif +#endif /* MLKEM_NATIVE_COMMON_H */ diff --git a/mlkem/config.h b/mlkem/config.h new file mode 100644 index 000000000..fae77e719 --- /dev/null +++ b/mlkem/config.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef MLKEM_NATIVE_CONFIG_H +#define MLKEM_NATIVE_CONFIG_H + +/****************************************************************************** + * Name: MLKEM_K + * + * Description: Determines the security level for ML-KEM + * - MLKEM_K=2 corresponds to ML-KEM-512 + * - MLKEM_K=3 corresponds to ML-KEM-768 + * - MLKEM_K=4 corresponds to ML-KEM-1024 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#ifndef MLKEM_K +#define MLKEM_K 3 /* Change this for different security strengths */ +#endif + +/****************************************************************************** + * Name: MLKEM_NATIVE_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of mlkem/config.h. + * + * This _must_ be set on the command line using + * `-DMLKEM_NATIVE_CONFIG_FILE="..."`. + * + * When you need to build mlkem-native in multiple configurations, + * using varying MLKEM_NATIE_CONFIG_FILE can be more convenient + * then configuring everything through CFLAGS. + * + *****************************************************************************/ +/* #define MLKEM_NATIVE_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLKEM_NAMESPACE + * _MLKEM_NAMESPACE + * + * Description: The macros to use to namespace global symbols + * from mlkem/. + *****************************************************************************/ +#define MLKEM_NAMESPACE(sym) MLKEM_DEFAULT_NAMESPACE(sym) +#define _MLKEM_NAMESPACE(sym) _MLKEM_DEFAULT_NAMESPACE(sym) + +/****************************************************************************** + * Name: FIPS202_NAMESPACE + * _FIPS202_NAMESPACE + * + * Description: The macros to use to namespace global symbols + * from fips202/. + *****************************************************************************/ +#define FIPS202_NAMESPACE(sym) FIPS202_DEFAULT_NAMESPACE(sym) +#define _FIPS202_NAMESPACE(sym) _FIPS202_DEFAULT_NAMESPACE(sym) + +/****************************************************************************** + * Name: MLKEM_USE_NATIVE + * + * Description: Determines whether a native backend should + * be used, if available. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#if !defined(MLKEM_USE_NATIVE) +/* #define MLKEM_USE_NATIVE */ +#endif + +/****************************************************************************** + * Name: MLKEM_NATIVE_ARITH_BACKEND + * + * Description: The arithmetic backend to use. + * + * This must be the filename of an arithmetic backend. + * See the existing backends for examples. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLKEM_USE_NATIVE) && !defined(MLKEM_NATIVE_ARITH_BACKEND) +#define MLKEM_NATIVE_ARITH_BACKEND "native/default.h" +#endif /* MLKEM_NATIVE_ARITH_BACKEND */ + +/****************************************************************************** + * Name: MLKEM_NATIVE_FIPS202_BACKEND + * + * Description: The FIPS-202 backend to use. + * + * This must be the filename of an FIPS-202 backend. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLKEM_USE_NATIVE) && !defined(MLKEM_NATIVE_FIPS202_BACKEND) +#define MLKEM_NATIVE_FIPS202_BACKEND "../fips202/native/default.h" +#endif /* MLKEM_NATIVE_FIPS202_BACKEND */ + +#endif /* MLkEM_NATIVE_CONFIG_H */ diff --git a/mlkem/debug/debug.c b/mlkem/debug/debug.c index 0dc2e8822..690977908 100644 --- a/mlkem/debug/debug.c +++ b/mlkem/debug/debug.c @@ -52,7 +52,6 @@ void mlkem_debug_print_error(const char *file, int line, const char *msg) } #else /* MLKEM_DEBUG */ -#include "params.h" #define empty_cu_debug MLKEM_NAMESPACE(empty_cu_debug) int empty_cu_debug; diff --git a/mlkem/debug/debug.h b/mlkem/debug/debug.h index 65208771d..5838ae4bf 100644 --- a/mlkem/debug/debug.h +++ b/mlkem/debug/debug.h @@ -5,6 +5,8 @@ #ifndef MLKEM_DEBUG_H #define MLKEM_DEBUG_H +#include "common.h" + #if defined(MLKEM_DEBUG) #include #include @@ -153,6 +155,9 @@ void mlkem_debug_print_error(const char *file, int line, const char *msg); "polyvec unsigned bound for " #ptr ".vec[i]"); \ } while (0) +#define MLKEM_CONCAT_(left, right) left##right +#define MLKEM_CONCAT(left, right) MLKEM_CONCAT_(left, right) + /* Following AWS-LC to define a C99-compliant static assert */ #define MLKEM_STATIC_ASSERT_DEFINE(cond, msg) \ typedef struct \ diff --git a/mlkem/indcpa.c b/mlkem/indcpa.c index bde832c18..ee2f140a0 100644 --- a/mlkem/indcpa.c +++ b/mlkem/indcpa.c @@ -10,14 +10,13 @@ #include "fips202x4.h" #include "indcpa.h" #include "ntt.h" -#include "params.h" #include "poly.h" #include "polyvec.h" #include "randombytes.h" #include "rej_uniform.h" #include "symmetric.h" -#include "arith_native.h" +#include "arith_backend.h" #include "debug/debug.h" #include "cbmc.h" diff --git a/mlkem/indcpa.h b/mlkem/indcpa.h index 0e6485312..7e2a0b247 100644 --- a/mlkem/indcpa.h +++ b/mlkem/indcpa.h @@ -7,10 +7,9 @@ #include #include "cbmc.h" -#include "params.h" +#include "common.h" #include "polyvec.h" - #define gen_matrix MLKEM_NAMESPACE(gen_matrix) /************************************************* * Name: gen_matrix diff --git a/mlkem/kem.c b/mlkem/kem.c index 1abce65e4..03e997af3 100644 --- a/mlkem/kem.c +++ b/mlkem/kem.c @@ -7,7 +7,6 @@ #include #include #include "indcpa.h" -#include "params.h" #include "randombytes.h" #include "symmetric.h" #include "verify.h" diff --git a/mlkem/namespace.h b/mlkem/namespace.h new file mode 100644 index 000000000..8c409fb0c --- /dev/null +++ b/mlkem/namespace.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef MLKEM_NATIVE_NAMESPACE_H +#define MLKEM_NATIVE_NAMESPACE_H + +#if !defined(MLKEM_NATIVE_ARITH_BACKEND_NAME) +#define MLKEM_NATIVE_ARITH_BACKEND_NAME C +#endif + +/* Don't change parameters below this line */ +#if (MLKEM_K == 2) +#define MLKEM_PARAM_NAME MLKEM512 +#elif (MLKEM_K == 3) +#define MLKEM_PARAM_NAME MLKEM768 +#elif (MLKEM_K == 4) +#define MLKEM_PARAM_NAME MLKEM1024 +#else +#error "MLKEM_K must be in {2,3,4}" +#endif + +#define ___MLKEM_DEFAULT_NAMESPACE(x1, x2, x3, x4) x1##_##x2##_##x3##_##x4 +#define __MLKEM_DEFAULT_NAMESPACE(x1, x2, x3, x4) \ + ___MLKEM_DEFAULT_NAMESPACE(x1, x2, x3, x4) + +/* + * NAMESPACE is PQCP_MLKEM_NATIVE___ + * e.g., PQCP_MLKEM_NATIVE_MLKEM512_AARCH64_OPT_ + */ +#define MLKEM_DEFAULT_NAMESPACE(s) \ + __MLKEM_DEFAULT_NAMESPACE(PQCP_MLKEM_NATIVE, MLKEM_PARAM_NAME, \ + MLKEM_NATIVE_ARITH_BACKEND_NAME, s) +#define _MLKEM_DEFAULT_NAMESPACE(s) \ + __MLKEM_DEFAULT_NAMESPACE(_PQCP_MLKEM_NATIVE, MLKEM_PARAM_NAME, \ + MLKEM_NATIVE_ARITH_BACKEND_NAME, s) + +#if !defined(MLKEM_NATIVE_FIPS202_BACKEND_NAME) +#define MLKEM_NATIVE_FIPS202_BACKEND_NAME C +#endif + +#define ___FIPS202_DEFAULT_NAMESPACE(x1, x2, x3) x1##_##x2##_##x3 +#define __FIPS202_DEFAULT_NAMESPACE(x1, x2, x3) \ + ___FIPS202_DEFAULT_NAMESPACE(x1, x2, x3) + +/* + * NAMESPACE is PQCP_MLKEM_NATIVE_FIPS202__ + * e.g., PQCP_MLKEM_NATIVE_FIPS202_X86_64_XKCP_ + */ +#define FIPS202_DEFAULT_NAMESPACE(s) \ + __FIPS202_DEFAULT_NAMESPACE(PQCP_MLKEM_NATIVE_FIPS202, \ + MLKEM_NATIVE_FIPS202_BACKEND_NAME, s) +#define _FIPS202_DEFAULT_NAMESPACE(s) \ + __FIPS202_DEFAULT_NAMESPACE(_PQCP_MLKEM_NATIVE_FIPS202, \ + MLKEM_NATIVE_FIPS202_BACKEND_NAME, s) + +#endif /* MLKEM_NATIVE_NAMESPACE_H */ diff --git a/mlkem/native/aarch64/README.md b/mlkem/native/aarch64/README.md index c21e27f36..e499a4a22 100644 --- a/mlkem/native/aarch64/README.md +++ b/mlkem/native/aarch64/README.md @@ -16,4 +16,4 @@ This backend comes with two profiles: "clean" and optimized. The "clean" backend read and modify; for example, is heavily leverages register aliases and assembly macros. The optimized profile is automatically generated from the clean profile via [SLOTHY](https://github.com/slothy-optimizer/slothy). Currently, the target architecture is Cortex-A55, but you can easily re-optimize the code for a different microarchitecture supported -by SLOTHY, by adjusting the parameters in [optimize.sh](optimize.sh). +by SLOTHY, by adjusting the parameters in [optimize.sh](src/optimize.sh). diff --git a/mlkem/native/aarch64/clean.h b/mlkem/native/aarch64/clean.h new file mode 100644 index 000000000..43a401dfc --- /dev/null +++ b/mlkem/native/aarch64/clean.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* ML-KEM arithmetic native profile for clean assembly */ + +#ifdef MLKEM_NATIVE_ARITH_PROFILE_H +#error Only one MLKEM_ARITH assembly profile can be defined -- did you include multiple profiles? +#else +#define MLKEM_NATIVE_ARITH_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN + +#define MLKEM_NATIVE_ARITH_BACKEND_NAME AARCH64_CLEAN + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_ARITH_BACKEND_IMPL "aarch64/src/clean_impl.h" + +#endif /* MLKEM_NATIVE_ARITH_PROFILE_H */ diff --git a/mlkem/native/aarch64/opt.h b/mlkem/native/aarch64/opt.h new file mode 100644 index 000000000..04323c3e7 --- /dev/null +++ b/mlkem/native/aarch64/opt.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* ML-KEM arithmetic native profile for clean assembly */ + +#ifdef MLKEM_NATIVE_ARITH_PROFILE_H +#error Only one MLKEM_ARITH assembly profile can be defined -- did you include multiple profiles? +#else +#define MLKEM_NATIVE_ARITH_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT + +#define MLKEM_NATIVE_ARITH_BACKEND_NAME AARCH64_OPT + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_ARITH_BACKEND_IMPL "aarch64/src/opt_impl.h" + +#endif /* MLKEM_NATIVE_ARITH_PROFILE_H */ diff --git a/mlkem/native/aarch64/aarch64_zetas.c b/mlkem/native/aarch64/src/aarch64_zetas.c similarity index 98% rename from mlkem/native/aarch64/aarch64_zetas.c rename to mlkem/native/aarch64/src/aarch64_zetas.c index f0a0d5546..ecf1b529a 100644 --- a/mlkem/native/aarch64/aarch64_zetas.c +++ b/mlkem/native/aarch64/src/aarch64_zetas.c @@ -8,9 +8,13 @@ * Do not modify it directly. */ -#include "arith_native_aarch64.h" +#include "common.h" + +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) || \ + defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) -#ifdef MLKEM_USE_NATIVE_AARCH64 +#include +#include "arith_native_aarch64.h" /* * Table of zeta values used in the AArch64 forward NTT @@ -163,10 +167,10 @@ const int16_t aarch64_zetas_mulcache_twisted_native[] = { -11566, 11566, }; -#else /* MLKEM_USE_NATIVE_AARCH64 */ +#else #include "params.h" /* Dummy declaration for compilers disliking empty compilation units */ #define empty_cu_aarch64_zetas MLKEM_NAMESPACE(empty_cu_aarch64_zetas) int empty_cu_aarch64_zetas; -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif diff --git a/mlkem/native/aarch64/arith_native_aarch64.h b/mlkem/native/aarch64/src/arith_native_aarch64.h similarity index 96% rename from mlkem/native/aarch64/arith_native_aarch64.h rename to mlkem/native/aarch64/src/arith_native_aarch64.h index f39eb9ac8..2f3b0ef4f 100644 --- a/mlkem/native/aarch64/arith_native_aarch64.h +++ b/mlkem/native/aarch64/src/arith_native_aarch64.h @@ -6,10 +6,7 @@ #define MLKEM_AARCH64_NATIVE_H #include -#include "config.h" -#include "params.h" - -#ifdef MLKEM_USE_NATIVE_AARCH64 +#include "common.h" #define aarch64_ntt_zetas_layer01234 \ MLKEM_NAMESPACE(aarch64_ntt_zetas_layer01234) @@ -72,6 +69,9 @@ void poly_mulcache_compute_asm_opt(int16_t *, const int16_t *, const int16_t *, #define poly_tobytes_asm_clean MLKEM_NAMESPACE(poly_tobytes_asm_clean) void poly_tobytes_asm_clean(uint8_t *r, const int16_t *a); +#define poly_tobytes_asm_opt MLKEM_NAMESPACE(poly_tobytes_asm_opt) +void poly_tobytes_asm_opt(uint8_t *r, const int16_t *a); + #define polyvec_basemul_acc_montgomery_cached_asm_clean \ MLKEM_NAMESPACE(polyvec_basemul_acc_montgomery_cached_asm_clean) void polyvec_basemul_acc_montgomery_cached_asm_clean(int16_t *r, @@ -85,6 +85,4 @@ void polyvec_basemul_acc_montgomery_cached_asm_opt(int16_t *r, const int16_t *a, const int16_t *b, const int16_t *b_cache); - -#endif /* MLKEM_USE_NATIVE_AARCH64 */ #endif /* MLKEM_AARCH64_NATIVE_H */ diff --git a/mlkem/native/aarch64/profiles/clean.h b/mlkem/native/aarch64/src/clean_impl.h similarity index 90% rename from mlkem/native/aarch64/profiles/clean.h rename to mlkem/native/aarch64/src/clean_impl.h index e7f71bd53..0a40199e7 100644 --- a/mlkem/native/aarch64/profiles/clean.h +++ b/mlkem/native/aarch64/src/clean_impl.h @@ -5,14 +5,14 @@ /* ML-KEM arithmetic native profile for clean assembly */ -#ifdef MLKEM_ARITH_NATIVE_PROFILE_H +#ifdef MLKEM_NATIVE_ARITH_PROFILE_IMPL_H #error Only one MLKEM_ARITH assembly profile can be defined -- did you include multiple profiles? #else -#define MLKEM_ARITH_NATIVE_PROFILE_H +#define MLKEM_NATIVE_ARITH_PROFILE_IMPL_H -#include "../../arith_native.h" -#include "../arith_native_aarch64.h" +#include "arith_native_aarch64.h" +/* Set of primitives that this backend replaces */ #define MLKEM_USE_NATIVE_NTT #define MLKEM_USE_NATIVE_INTT #define MLKEM_USE_NATIVE_POLY_REDUCE @@ -22,7 +22,6 @@ #define MLKEM_USE_NATIVE_POLY_TOBYTES #define MLKEM_USE_NATIVE_REJ_UNIFORM -#define NTT_BOUND_NATIVE (6 * MLKEM_Q) static INLINE void ntt_native(poly *data) { ntt_asm_clean(data->coeffs, aarch64_ntt_zetas_layer01234, @@ -75,4 +74,4 @@ static INLINE int rej_uniform_native(int16_t *r, unsigned int len, return (int)rej_uniform_asm_clean(r, buf, buflen); } -#endif /* MLKEM_ARITH_NATIVE_PROFILE_H */ +#endif /* MLKEM_NATIVE_ARITH_PROFILE_IMPL_H */ diff --git a/mlkem/native/aarch64/common.i b/mlkem/native/aarch64/src/common.i similarity index 100% rename from mlkem/native/aarch64/common.i rename to mlkem/native/aarch64/src/common.i diff --git a/mlkem/native/aarch64/consts.h b/mlkem/native/aarch64/src/consts.h similarity index 96% rename from mlkem/native/aarch64/consts.h rename to mlkem/native/aarch64/src/consts.h index 0e834bed4..c40947299 100644 --- a/mlkem/native/aarch64/consts.h +++ b/mlkem/native/aarch64/src/consts.h @@ -7,7 +7,7 @@ #define MLKEM_NATIVE_AARCH64_CONSTS #include -#include "params.h" +#include "common.h" #define zetas_mulcache_native MLKEM_NAMESPACE(zetas_mulcache_native) extern const int16_t zetas_mulcache_native[256]; diff --git a/mlkem/native/aarch64/intt_clean.S b/mlkem/native/aarch64/src/intt_clean.S similarity index 98% rename from mlkem/native/aarch64/intt_clean.S rename to mlkem/native/aarch64/src/intt_clean.S index 2ac4e0f15..2f05d8cca 100644 --- a/mlkem/native/aarch64/intt_clean.S +++ b/mlkem/native/aarch64/src/intt_clean.S @@ -23,8 +23,8 @@ /// SOFTWARE. /// -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) // Needed to provide ASM_LOAD directive #include "common.i" @@ -371,4 +371,4 @@ layer012_start: pop_stack ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN */ diff --git a/mlkem/native/aarch64/intt_opt.S b/mlkem/native/aarch64/src/intt_opt.S similarity index 99% rename from mlkem/native/aarch64/intt_opt.S rename to mlkem/native/aarch64/src/intt_opt.S index 48c412f36..fc720e504 100644 --- a/mlkem/native/aarch64/intt_opt.S +++ b/mlkem/native/aarch64/src/intt_opt.S @@ -23,8 +23,8 @@ /// SOFTWARE. /// -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) // Needed to provide ASM_LOAD directive #include "common.i" @@ -1027,4 +1027,4 @@ layer012_start: pop_stack ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT */ diff --git a/mlkem/native/aarch64/ntt_clean.S b/mlkem/native/aarch64/src/ntt_clean.S similarity index 98% rename from mlkem/native/aarch64/ntt_clean.S rename to mlkem/native/aarch64/src/ntt_clean.S index 4243b9431..ad9086e27 100644 --- a/mlkem/native/aarch64/ntt_clean.S +++ b/mlkem/native/aarch64/src/ntt_clean.S @@ -24,8 +24,8 @@ /// SOFTWARE. /// -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) // Needed to provide ASM_LOAD directive #include "common.i" @@ -295,4 +295,4 @@ layer3456_start: pop_stack ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN */ diff --git a/mlkem/native/aarch64/ntt_opt.S b/mlkem/native/aarch64/src/ntt_opt.S similarity index 99% rename from mlkem/native/aarch64/ntt_opt.S rename to mlkem/native/aarch64/src/ntt_opt.S index 71779afe9..f4cbc928f 100644 --- a/mlkem/native/aarch64/ntt_opt.S +++ b/mlkem/native/aarch64/src/ntt_opt.S @@ -24,8 +24,8 @@ /// SOFTWARE. /// -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) // Needed to provide ASM_LOAD directive #include "common.i" @@ -892,4 +892,4 @@ layer3456_start: pop_stack ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT */ diff --git a/mlkem/native/aarch64/profiles/opt.h b/mlkem/native/aarch64/src/opt_impl.h similarity index 89% rename from mlkem/native/aarch64/profiles/opt.h rename to mlkem/native/aarch64/src/opt_impl.h index 2414700bf..bc9af0dee 100644 --- a/mlkem/native/aarch64/profiles/opt.h +++ b/mlkem/native/aarch64/src/opt_impl.h @@ -5,14 +5,14 @@ /* ML-KEM arithmetic native profile for clean assembly */ -#ifdef MLKEM_ARITH_NATIVE_PROFILE_H +#ifdef MLKEM_NATIVE_ARITH_PROFILE_IMPL_H #error Only one MLKEM_ARITH assembly profile can be defined -- did you include multiple profiles? #else -#define MLKEM_ARITH_NATIVE_PROFILE_H +#define MLKEM_NATIVE_ARITH_PROFILE_IMPL_H -#include "../../arith_native.h" -#include "../arith_native_aarch64.h" +#include "arith_native_aarch64.h" +/* Set of primitives that this backend replaces */ #define MLKEM_USE_NATIVE_NTT #define MLKEM_USE_NATIVE_INTT #define MLKEM_USE_NATIVE_POLY_REDUCE @@ -62,7 +62,7 @@ static INLINE void polyvec_basemul_acc_montgomery_cached_native( static INLINE void poly_tobytes_native(uint8_t r[MLKEM_POLYBYTES], const poly *a) { - poly_tobytes_asm_clean(r, a->coeffs); + poly_tobytes_asm_opt(r, a->coeffs); } static INLINE int rej_uniform_native(int16_t *r, unsigned int len, @@ -75,4 +75,4 @@ static INLINE int rej_uniform_native(int16_t *r, unsigned int len, return (int)rej_uniform_asm_clean(r, buf, buflen); } -#endif /* MLKEM_ARITH_NATIVE_PROFILE_H */ +#endif /* MLKEM_NATIVE_ARITH_PROFILE_IMPL_H */ diff --git a/mlkem/native/aarch64/optimize.sh b/mlkem/native/aarch64/src/optimize.sh similarity index 100% rename from mlkem/native/aarch64/optimize.sh rename to mlkem/native/aarch64/src/optimize.sh diff --git a/mlkem/native/aarch64/poly_clean.S b/mlkem/native/aarch64/src/poly_clean.S similarity index 98% rename from mlkem/native/aarch64/poly_clean.S rename to mlkem/native/aarch64/src/poly_clean.S index 86e4e494a..3e1bc5cf4 100644 --- a/mlkem/native/aarch64/poly_clean.S +++ b/mlkem/native/aarch64/src/poly_clean.S @@ -3,8 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) // Needed to provide ASM_LOAD directive #include "common.i" @@ -285,4 +285,4 @@ poly_tomont_asm_loop: ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN */ diff --git a/mlkem/native/aarch64/poly_opt.S b/mlkem/native/aarch64/src/poly_opt.S similarity index 99% rename from mlkem/native/aarch64/poly_opt.S rename to mlkem/native/aarch64/src/poly_opt.S index d86595059..df3b21008 100644 --- a/mlkem/native/aarch64/poly_opt.S +++ b/mlkem/native/aarch64/src/poly_opt.S @@ -3,8 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) // Needed to provide ASM_LOAD directive #include "common.i" @@ -649,4 +649,4 @@ poly_tomont_asm_loop: ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT */ diff --git a/mlkem/native/aarch64/polyvec_clean.S b/mlkem/native/aarch64/src/polyvec_clean.S similarity index 98% rename from mlkem/native/aarch64/polyvec_clean.S rename to mlkem/native/aarch64/src/polyvec_clean.S index 59f57d77a..bfd1d2b8a 100644 --- a/mlkem/native/aarch64/polyvec_clean.S +++ b/mlkem/native/aarch64/src/polyvec_clean.S @@ -9,8 +9,8 @@ // https://eprint.iacr.org/2021/986 // https://github.com/neon-ntt/neon-ntt -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) #include "params.h" @@ -279,4 +279,4 @@ k4_loop_start: ret #endif /* MLKEM_K == 4 */ -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN */ diff --git a/mlkem/native/aarch64/polyvec_opt.S b/mlkem/native/aarch64/src/polyvec_opt.S similarity index 99% rename from mlkem/native/aarch64/polyvec_opt.S rename to mlkem/native/aarch64/src/polyvec_opt.S index 9ae035639..07dc98efd 100644 --- a/mlkem/native/aarch64/polyvec_opt.S +++ b/mlkem/native/aarch64/src/polyvec_opt.S @@ -6,12 +6,11 @@ // AArch64 re-implementation of the asymmetric base multiplication from: // Neon NTT: Faster Dilithium, Kyber, and Saber on Cortex-A72 and Apple M1 -// https: // eprint.iacr.org/2021/986 -// https: // github.com/neon-ntt/neon-ntt - -#include "config.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +// https://eprint.iacr.org/2021/986 +// https://github.com/neon-ntt/neon-ntt +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) #include "params.h" // Needed to provide ASM_LOAD directive @@ -1122,4 +1121,4 @@ k4_loop_start: ret #endif /* MLKEM_K == 4 */ -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT */ diff --git a/mlkem/native/aarch64/rej_uniform_asm_clean.S b/mlkem/native/aarch64/src/rej_uniform_asm_clean.S similarity index 99% rename from mlkem/native/aarch64/rej_uniform_asm_clean.S rename to mlkem/native/aarch64/src/rej_uniform_asm_clean.S index 00332ec65..c51e53188 100644 --- a/mlkem/native/aarch64/rej_uniform_asm_clean.S +++ b/mlkem/native/aarch64/src/rej_uniform_asm_clean.S @@ -18,9 +18,9 @@ * * Returns number of sampled 16-bit integers (at most MLKEM_N). **************************************************/ -#include "config.h" -#include "params.h" -#if defined(MLKEM_USE_NATIVE_AARCH64) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) || \ + defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) // Needed to provide ASM_LOAD directive #include "common.i" @@ -605,4 +605,5 @@ return: pop_stack ret -#endif /* MLKEM_USE_NATIVE_AARCH64 */ +#endif /* defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) || + defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) */ diff --git a/mlkem/native/arith_native.h b/mlkem/native/api.h similarity index 98% rename from mlkem/native/arith_native.h rename to mlkem/native/api.h index b7e921323..5a2d92b1d 100644 --- a/mlkem/native/arith_native.h +++ b/mlkem/native/api.h @@ -6,14 +6,12 @@ #define MLKEM_ARITH_NATIVE_H #include -#include "config.h" -#include "params.h" - -#if defined(MLKEM_USE_NATIVE) +#include "cbmc.h" #include "poly.h" #include "polyvec.h" -#include "profile.h" + +#include "common.h" /* * MLKEM native arithmetic interface @@ -246,5 +244,4 @@ static INLINE int rej_uniform_native(int16_t *r, unsigned int len, const uint8_t *buf, unsigned int buflen); #endif /* MLKEM_USE_NATIVE_REJ_UNIFORM */ -#endif /* MLKEM_USE_NATIVE */ #endif /* MLKEM_ARITH_NATIVE_H */ diff --git a/mlkem/native/default.h b/mlkem/native/default.h new file mode 100644 index 000000000..d1e41c52e --- /dev/null +++ b/mlkem/native/default.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef MLKEM_NATIVE_ARITH_BACKEND_DEFAULT_H +#define MLKEM_NATIVE_ARITH_BACKEND_DEFAULT_H + +/* + * Default arithmetic backend + */ +#include "sys.h" + +#ifdef SYS_AARCH64 +/* + * For AArch64, we currently we have one clean and one opt profile. + * We default to the opt profile. + * + * In the future, this may branch further depending on the microarchitecture. + */ +#include "aarch64/opt.h" +#endif /* SYS_AARCH64 */ + +#ifdef SYS_X86_64_AVX2 +/* + * For now, there's only one x86_64 profile, based on + * the AVX2 code from the Kyber repository. + * https://github.com/pq-crystals/kyber + */ +#include "x86_64/default.h" +#endif /* SYS_X86_64 */ + +#endif /* MLKEM_NATIVE_ARITH_BACKEND_DEFAULT_H */ diff --git a/mlkem/native/profile.h b/mlkem/native/profile.h deleted file mode 100644 index ab9d93aa1..000000000 --- a/mlkem/native/profile.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef MLKEM_ARITH_NATIVE_PROFILE_CHOICE_H -#define MLKEM_ARITH_NATIVE_PROFILE_CHOICE_H - -#include -#include "config.h" -#include "params.h" - -#if defined(MLKEM_USE_NATIVE) -#include "poly.h" -#include "polyvec.h" - -/* - * MLKEM native arithmetic profile - * - * The profile decides which implementation(s) of the arithmetic backend to use. - * - * If you don't change anything, the default profile will be used. This profile - * picks implementations based on characteristics of your system visible to - * the compiler. - * - * If you want to pick a specific profile for your target, there are three ways - * to do so, in descending order of convenience to the user: - * 1. Pick one of the profiles shipped with this repository. - * 2. Provide your own profile and register it via MLKEM_ARITH_NATIVE_PROFILE - * (which must be the profile's path relative to this directoru). - * 3. Set MLKEM_ARITH_NATIVE_MANUAL and use an adhoc profile specified via - * CFLAGS. - */ - -/* Option 2: Manually written profile */ -#if defined(MLKEM_ARITH_NATIVE_PROFILE) - -#define STRINGIFY_(x) #x -#define STRINGIFY(x) STRINGIFY_(x) -#include STRINGIFY(MLKEM_ARITH_NATIVE_PROFILE) - -/* Option 1: Choose from shipped list of profiles */ -#elif !defined(MLKEM_ARITH_NATIVE_MANUAL) - -#ifdef SYS_AARCH64 -/* - * For now, we only have clean and opt profiles. - * In the future, this is likely to branch further depending - * on the microarchitecture. - */ -#if defined(MLKEM_USE_NATIVE_AARCH64_CLEAN) -#include "aarch64/profiles/clean.h" -#else /* MLKEM_USE_NATIVE_AARCH64_CLEAN */ -#include "aarch64/profiles/opt.h" -#endif /* !MLKEM_USE_NATIVE_AARCH64_CLEAN */ -#endif /* SYS_AARCH64 */ - -#ifdef SYS_X86_64_AVX2 -/* - * For now, there's only one x86_64 profile, which is essentially - * the AVX2 code from the Kyber repository - * https://github.com/pq-crystals/kyber - */ -#include "x86_64/profiles/default.h" -#endif /* SYS_X86_64 */ - -#else /* !MLKEM_ARITH_NATIVE_PROFILE && MLKEM_ARITH_NATIVE_MANUAL */ - -/* Option 3: Build your own profile here, or via CFLAGS */ - -#endif /* !MLKEM_ARITH_NATIVE_PROFILE && !MLKEM_ARITH_NATIVE_MANUAL */ - -#endif /* MLKEM_USE_NATIVE */ -#endif /* MLKEM_ARITH_NATIVE_PROFILE_CHOICE_H */ diff --git a/mlkem/native/x86_64/default.h b/mlkem/native/x86_64/default.h new file mode 100644 index 000000000..592e8996d --- /dev/null +++ b/mlkem/native/x86_64/default.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* ML-KEM arithmetic native profile for clean assembly */ + +#ifdef MLKEM_NATIVE_ARITH_PROFILE_H +#error Only one MLKEM_ARITH assembly profile can be defined -- did you include multiple profiles? +#else +#define MLKEM_NATIVE_ARITH_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT + +#define MLKEM_NATIVE_ARITH_BACKEND_NAME X86_64_DEFAULT + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_ARITH_BACKEND_IMPL "x86_64/src/default_impl.h" + +#endif /* MLKEM_NATIVE_ARITH_PROFILE_H */ diff --git a/mlkem/native/x86_64/align.h b/mlkem/native/x86_64/src/align.h similarity index 100% rename from mlkem/native/x86_64/align.h rename to mlkem/native/x86_64/src/align.h diff --git a/mlkem/native/x86_64/arith_native_x86_64.h b/mlkem/native/x86_64/src/arith_native_x86_64.h similarity index 91% rename from mlkem/native/x86_64/arith_native_x86_64.h rename to mlkem/native/x86_64/src/arith_native_x86_64.h index b346e1eb2..4b78c004a 100644 --- a/mlkem/native/x86_64/arith_native_x86_64.h +++ b/mlkem/native/x86_64/src/arith_native_x86_64.h @@ -5,16 +5,13 @@ #ifndef MLKEM_X86_64_NATIVE_H #define MLKEM_X86_64_NATIVE_H -#include -#include "config.h" -#include "fips202.h" -#include "params.h" -#include "polyvec.h" - -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#include "common.h" #include #include +#include "consts.h" +#include "fips202.h" +#include "polyvec.h" #define REJ_UNIFORM_AVX_NBLOCKS \ ((12 * MLKEM_N / 8 * (1 << 12) / MLKEM_Q + SHAKE128_RATE) / SHAKE128_RATE) @@ -57,6 +54,4 @@ void nttfrombytes_avx2(__m256i *r, const uint8_t *a, const __m256i *qdata); #define tomont_avx2 MLKEM_NAMESPACE(tomont_avx2) void tomont_avx2(__m256i *r, const __m256i *qdata); -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ - #endif /* MLKEM_X86_64_NATIVE_H */ diff --git a/mlkem/native/x86_64/basemul.S b/mlkem/native/x86_64/src/basemul.S similarity index 96% rename from mlkem/native/x86_64/basemul.S rename to mlkem/native/x86_64/src/basemul.S index 797b0f46a..503fbeb51 100644 --- a/mlkem/native/x86_64/basemul.S +++ b/mlkem/native/x86_64/src/basemul.S @@ -6,9 +6,8 @@ // Implementation from Kyber reference repository // https://github.com/pq-crystals/kyber/blob/main/avx2 -#include "config.h" - -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include "consts.h" #include "params.h" @@ -135,4 +134,4 @@ schoolbook 3 mov %r8,%rsp ret -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/basemul.c b/mlkem/native/x86_64/src/basemul.c similarity index 90% rename from mlkem/native/x86_64/basemul.c rename to mlkem/native/x86_64/src/basemul.c index c9dba813f..3f1653ed3 100644 --- a/mlkem/native/x86_64/basemul.c +++ b/mlkem/native/x86_64/src/basemul.c @@ -3,15 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "config.h" +#include "common.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) -#include "arith_native_x86_64.h" #include "consts.h" #include "poly.h" #include "polyvec.h" +#include "arith_native_x86_64.h" + static void poly_basemul_montgomery_avx2(poly *r, const poly *a, const poly *b) { basemul_avx2((__m256i *)r->coeffs, (const __m256i *)a->coeffs, @@ -57,12 +58,11 @@ void polyvec_basemul_acc_montgomery_cached_avx2(poly *r, const polyvec *a, } } -#else -#include "params.h" +#else /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ /* Dummy constant to keep compiler happy despite empty CU */ #define empty_cu_avx2_basemul MLKEM_NAMESPACE(empty_cu_avx2_basemul) int empty_cu_avx2_basemul; -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/consts.c b/mlkem/native/x86_64/src/consts.c similarity index 92% rename from mlkem/native/x86_64/consts.c rename to mlkem/native/x86_64/src/consts.c index 573eabb64..9b6d0993e 100644 --- a/mlkem/native/x86_64/consts.c +++ b/mlkem/native/x86_64/src/consts.c @@ -8,13 +8,12 @@ * https://github.com/pq-crystals/kyber/blob/main/avx2/consts.c */ -#include "config.h" +#include "common.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include "align.h" #include "consts.h" -#include "params.h" #define Q MLKEM_Q #define MONT -1044 /* 2^16 mod q */ @@ -86,10 +85,9 @@ const qdata_t qdata = {{ SHIFT, SHIFT, SHIFT, SHIFT, SHIFT, SHIFT, SHIFT, SHIFT, SHIFT, SHIFT}}; -#else /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ -#include "params.h" +#else /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ /* Dummy declaration for compilers disliking empty compilation units */ #define empty_cu_consts MLKEM_NAMESPACE(empty_cu_consts) int empty_cu_consts; -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/consts.h b/mlkem/native/x86_64/src/consts.h similarity index 97% rename from mlkem/native/x86_64/consts.h rename to mlkem/native/x86_64/src/consts.h index 8ca98bbf8..a9f0c484f 100644 --- a/mlkem/native/x86_64/consts.h +++ b/mlkem/native/x86_64/src/consts.h @@ -11,7 +11,7 @@ #ifndef CONSTS_H #define CONSTS_H -#include "params.h" +#include "common.h" #define _16XQ 0 #define _16XQINV 16 diff --git a/mlkem/native/x86_64/profiles/default.h b/mlkem/native/x86_64/src/default_impl.h similarity index 92% rename from mlkem/native/x86_64/profiles/default.h rename to mlkem/native/x86_64/src/default_impl.h index 55eb0ad01..4f3cd2c9a 100644 --- a/mlkem/native/x86_64/profiles/default.h +++ b/mlkem/native/x86_64/src/default_impl.h @@ -5,17 +5,14 @@ /* ML-KEM arithmetic native profile for clean assembly */ -#ifdef MLKEM_ARITH_NATIVE_PROFILE_H +#ifdef MLKEM_NATIVE_ARITH_PROFILE_IMPL_H #error Only one MLKEM_ARITH assembly profile can be defined -- did you include multiple profiles? #else -#define MLKEM_ARITH_NATIVE_PROFILE_H +#define MLKEM_NATIVE_ARITH_PROFILE_IMPL_H #include -#include "../../arith_native.h" -#include "../arith_native_x86_64.h" -#include "../consts.h" - +#include "arith_native_x86_64.h" #include "poly.h" #define MLKEM_USE_NATIVE_NTT_CUSTOM_ORDER @@ -96,4 +93,4 @@ static INLINE void poly_frombytes_native(poly *r, nttfrombytes_avx2((__m256i *)r->coeffs, a, qdata.vec); } -#endif /* MLKEM_ARITH_NATIVE_PROFILE_H */ +#endif /* MLKEM_NATIVE_ARITH_PROFILE_IMPL_H */ diff --git a/mlkem/native/x86_64/fq.S b/mlkem/native/x86_64/src/fq.S similarity index 91% rename from mlkem/native/x86_64/fq.S rename to mlkem/native/x86_64/src/fq.S index 00fb093c5..50ef190b7 100644 --- a/mlkem/native/x86_64/fq.S +++ b/mlkem/native/x86_64/src/fq.S @@ -11,13 +11,12 @@ // in [0,1,...,q-1] rather than [0,1,...,q], matching the // semantics of poly_reduce(). -#include "config.h" -#include "params.h" +#include "common.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include "consts.h" -.include "fq.inc" +#include "fq.inc" .text reduce128_avx2: @@ -115,4 +114,4 @@ add $256,%rdi call tomont128_avx2 ret -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/fq.inc b/mlkem/native/x86_64/src/fq.inc similarity index 100% rename from mlkem/native/x86_64/fq.inc rename to mlkem/native/x86_64/src/fq.inc diff --git a/mlkem/native/x86_64/intt.S b/mlkem/native/x86_64/src/intt.S similarity index 97% rename from mlkem/native/x86_64/intt.S rename to mlkem/native/x86_64/src/intt.S index 8418cc471..4860985ed 100644 --- a/mlkem/native/x86_64/intt.S +++ b/mlkem/native/x86_64/src/intt.S @@ -8,14 +8,15 @@ * * Changes to placement of modular reductions have * been made to simplify reasoning of non-overflow */ -#include "config.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#include "common.h" + +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include "consts.h" #include "params.h" -.include "shuffle.inc" -.include "fq.inc" +#include "shuffle.inc" +#include "fq.inc" /* Compute four GS butterflies between rh{0,1,2,3} and rl{0,1,2,3}. * Butterflies 0,1 use root zh0 and twisted root zl0, and butterflies @@ -252,4 +253,4 @@ intt_level6 0 intt_level6 1 ret -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/ntt.S b/mlkem/native/x86_64/src/ntt.S similarity index 97% rename from mlkem/native/x86_64/ntt.S rename to mlkem/native/x86_64/src/ntt.S index f159faf4f..a0b6f734c 100644 --- a/mlkem/native/x86_64/ntt.S +++ b/mlkem/native/x86_64/src/ntt.S @@ -6,14 +6,13 @@ // Implementation from Kyber reference repository // https://github.com/pq-crystals/kyber/blob/main/avx2 -#include "config.h" - -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#include "common.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include "consts.h" #include "params.h" -.include "shuffle.inc" +#include "shuffle.inc" /* Compute steps 1,2 / 3 of Montgomery multiplication */ .macro mul rh0,rh1,rh2,rh3,zl0=15,zl1=15,zh0=2,zh1=2 @@ -219,4 +218,4 @@ levels1t6 1 ret -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/rej_uniform_avx2.c b/mlkem/native/x86_64/src/rej_uniform_avx2.c similarity index 98% rename from mlkem/native/x86_64/rej_uniform_avx2.c rename to mlkem/native/x86_64/src/rej_uniform_avx2.c index c6e663f7d..c3c8b8104 100644 --- a/mlkem/native/x86_64/rej_uniform_avx2.c +++ b/mlkem/native/x86_64/src/rej_uniform_avx2.c @@ -8,18 +8,15 @@ * https://github.com/pq-crystals/kyber/blob/main/avx2 */ -#include "config.h" +#include "common.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) - -#include "arith_native_x86_64.h" +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include #include #include +#include "arith_native_x86_64.h" #include "consts.h" -#include "params.h" - /* #define BMI */ #ifndef BMI @@ -290,10 +287,9 @@ unsigned int rej_uniform_avx2(int16_t *RESTRICT r, const uint8_t *buf) return ctr; } -#else /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ -#include "params.h" +#else /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ /* Dummy declaration for compilers disliking empty compilation units */ #define empty_cu_rej_uniform_avx2 MLKEM_NAMESPACE(empty_cu_rej_uniform_avx2) int empty_cu_rej_uniform_avx2; -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/shuffle.S b/mlkem/native/x86_64/src/shuffle.S similarity index 96% rename from mlkem/native/x86_64/shuffle.S rename to mlkem/native/x86_64/src/shuffle.S index dd1243121..34f6b30b0 100644 --- a/mlkem/native/x86_64/shuffle.S +++ b/mlkem/native/x86_64/src/shuffle.S @@ -6,14 +6,14 @@ // Implementation from Kyber reference repository // https://github.com/pq-crystals/kyber/blob/main/avx2 -#include "config.h" +#include "common.h" -#if defined(MLKEM_USE_NATIVE_X86_64) && defined(SYS_X86_64_AVX2) +#if defined(MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT) #include "consts.h" #include "params.h" -.include "fq.inc" -.include "shuffle.inc" +#include "fq.inc" +#include "shuffle.inc" .global MLKEM_NAMESPACE(nttpack_avx2) MLKEM_NAMESPACE(nttpack_avx2): @@ -255,4 +255,4 @@ add $192,%rsi call nttfrombytes128_avx ret -#endif /* MLKEM_USE_NATIVE_X86_64 && SYS_X86_64_AVX2 */ +#endif /* MLKEM_NATIVE_ARITH_BACKEND_X86_64_DEFAULT */ diff --git a/mlkem/native/x86_64/shuffle.inc b/mlkem/native/x86_64/src/shuffle.inc similarity index 100% rename from mlkem/native/x86_64/shuffle.inc rename to mlkem/native/x86_64/src/shuffle.inc diff --git a/mlkem/native/x86_64/x86_64_zetas.i b/mlkem/native/x86_64/src/x86_64_zetas.i similarity index 100% rename from mlkem/native/x86_64/x86_64_zetas.i rename to mlkem/native/x86_64/src/x86_64_zetas.i diff --git a/mlkem/ntt.c b/mlkem/ntt.c index 8de1c5446..178e8467c 100644 --- a/mlkem/ntt.c +++ b/mlkem/ntt.c @@ -2,14 +2,12 @@ * Copyright (c) 2024 The mlkem-native project authors * SPDX-License-Identifier: Apache-2.0 */ -#include "ntt.h" #include -#include "params.h" -#include "reduce.h" -#include "arith_native.h" +#include "arith_backend.h" #include "debug/debug.h" #include "ntt.h" +#include "reduce.h" #if !defined(MLKEM_USE_NATIVE_NTT) /* diff --git a/mlkem/ntt.h b/mlkem/ntt.h index 68c9e6724..efa38ecc9 100644 --- a/mlkem/ntt.h +++ b/mlkem/ntt.h @@ -6,9 +6,8 @@ #define NTT_H #include -#include "arith_native.h" #include "cbmc.h" -#include "params.h" +#include "common.h" #include "poly.h" #include "reduce.h" diff --git a/mlkem/params.h b/mlkem/params.h index 85797f067..586c31d33 100644 --- a/mlkem/params.h +++ b/mlkem/params.h @@ -5,47 +5,12 @@ #ifndef PARAMS_H #define PARAMS_H -#include "common.h" #include "config.h" -#include "cpucap.h" -#ifndef MLKEM_K -#define MLKEM_K 3 /* Change this for different security strengths */ +#if !defined(MLKEM_K) +#error MLKEM_K is not defined #endif -#if defined(MLKEM_USE_NATIVE_X86_64) -#define MLKEM_NATIVE_BACKEND X86_64 -#elif defined(MLKEM_USE_NATIVE_AARCH64) -#define MLKEM_NATIVE_BACKEND AARCH64 -#else -#define MLKEM_NATIVE_BACKEND C -#endif - -/* Don't change parameters below this line */ -#if (MLKEM_K == 2) -#define MLKEM_PARAM_NAME MLKEM512 -#elif (MLKEM_K == 3) -#define MLKEM_PARAM_NAME MLKEM768 -#elif (MLKEM_K == 4) -#define MLKEM_PARAM_NAME MLKEM1024 -#else -#error "MLKEM_K must be in {2,3,4}" -#endif - -#define ___MLKEM_NAMESPACE(x1, x2, x3, x4) x1##_##x2##_##x3##_##x4 -#define __MLKEM_NAMESPACE(x1, x2, x3, x4) ___MLKEM_NAMESPACE(x1, x2, x3, x4) - -/* - * NAMESPACE is PQCP_MLKEM_NATIVE___ - * e.g., PQCP_MLKEM_NATIVE_MLKEM512_AARCH64_ - */ -#define MLKEM_NAMESPACE(s) \ - __MLKEM_NAMESPACE(PQCP_MLKEM_NATIVE, MLKEM_PARAM_NAME, MLKEM_NATIVE_BACKEND, \ - s) -#define _MLKEM_NAMESPACE(s) \ - __MLKEM_NAMESPACE(_PQCP_MLKEM_NATIVE, MLKEM_PARAM_NAME, \ - MLKEM_NATIVE_BACKEND, s) - #define MLKEM_N 256 #define MLKEM_Q 3329 #define UINT12_MAX 4095 diff --git a/mlkem/poly.c b/mlkem/poly.c index fdc0ef4af..db7d64ebf 100644 --- a/mlkem/poly.c +++ b/mlkem/poly.c @@ -2,21 +2,20 @@ * Copyright (c) 2024 The mlkem-native project authors * SPDX-License-Identifier: Apache-2.0 */ -#include "poly.h" #include #include + +#include "arith_backend.h" #include "cbd.h" #include "cbmc.h" +#include "debug/debug.h" #include "fips202x4.h" #include "ntt.h" -#include "params.h" +#include "poly.h" #include "reduce.h" #include "symmetric.h" #include "verify.h" -#include "arith_native.h" -#include "debug/debug.h" - void poly_compress_du(uint8_t r[MLKEM_POLYCOMPRESSEDBYTES_DU], const poly *a) { int j; diff --git a/mlkem/poly.h b/mlkem/poly.h index 6d119539d..19cf7b96b 100644 --- a/mlkem/poly.h +++ b/mlkem/poly.h @@ -8,7 +8,7 @@ #include #include #include "cbmc.h" -#include "params.h" +#include "common.h" #include "reduce.h" #include "verify.h" diff --git a/mlkem/polyvec.c b/mlkem/polyvec.c index 7f268ee50..72277a626 100644 --- a/mlkem/polyvec.c +++ b/mlkem/polyvec.c @@ -4,10 +4,9 @@ */ #include "polyvec.h" #include -#include "arith_native.h" +#include "arith_backend.h" #include "config.h" #include "ntt.h" -#include "params.h" #include "poly.h" #include "debug/debug.h" diff --git a/mlkem/polyvec.h b/mlkem/polyvec.h index a4a03bf6d..cd90734fa 100644 --- a/mlkem/polyvec.h +++ b/mlkem/polyvec.h @@ -6,7 +6,7 @@ #define POLYVEC_H #include -#include "params.h" +#include "common.h" #include "poly.h" typedef struct diff --git a/mlkem/reduce.h b/mlkem/reduce.h index 39e85588a..515f706fa 100644 --- a/mlkem/reduce.h +++ b/mlkem/reduce.h @@ -7,8 +7,8 @@ #include #include "cbmc.h" +#include "common.h" #include "debug/debug.h" -#include "params.h" #define HALF_Q ((MLKEM_Q + 1) / 2) /* 1665 */ diff --git a/mlkem/rej_uniform.c b/mlkem/rej_uniform.c index 4e8a5ce9b..88102b4d7 100644 --- a/mlkem/rej_uniform.c +++ b/mlkem/rej_uniform.c @@ -2,10 +2,9 @@ * Copyright (c) 2024 The mlkem-native project authors * SPDX-License-Identifier: Apache-2.0 */ -#include "params.h" -#include "arith_native.h" #include "rej_uniform.h" +#include "arith_backend.h" /************************************************* * Name: rej_uniform_scalar diff --git a/mlkem/rej_uniform.h b/mlkem/rej_uniform.h index 7b86fa63e..e422f73cf 100644 --- a/mlkem/rej_uniform.h +++ b/mlkem/rej_uniform.h @@ -8,7 +8,7 @@ #include #include #include "cbmc.h" -#include "params.h" +#include "common.h" #define rej_uniform MLKEM_NAMESPACE(rej_uniform) /************************************************* diff --git a/mlkem/symmetric.h b/mlkem/symmetric.h index 4eb6aaba6..55ebbbd53 100644 --- a/mlkem/symmetric.h +++ b/mlkem/symmetric.h @@ -7,11 +7,9 @@ #include #include -#include "params.h" - -#include "fips202.h" - #include "cbmc.h" +#include "common.h" +#include "fips202.h" /* Macros denoting FIPS-203 specific Hash functions */ diff --git a/mlkem/sys/cpucap.h b/mlkem/sys.h similarity index 53% rename from mlkem/sys/cpucap.h rename to mlkem/sys.h index 7c3a1cdec..be3070dc2 100644 --- a/mlkem/sys/cpucap.h +++ b/mlkem/sys.h @@ -2,9 +2,8 @@ * Copyright (c) 2024 The mlkem-native project authors * SPDX-License-Identifier: Apache-2.0 */ - -#ifndef CPUCAP_H -#define CPUCAP_H +#ifndef MLKEM_NATIVE_SYS_H +#define MLKEM_NATIVE_SYS_H /* Check if we're running on an AArch64 little endian system. _M_ARM64 is set by * MSVC. */ @@ -52,4 +51,56 @@ #error "FORCE_X86_64 is set, but we don't seem to be on an X86_64 system." #endif +/* + * C90 does not have the inline compiler directive yet. + * We don't use it in C90 builds. + * However, in that case the compiler warns about some inline functions in + * header files not being used in every compilation unit that includes that + * header. To work around it we silence that warning in that case using + * __attribute__((unused)). + */ + +/* Do not use inline for C90 builds*/ +#if !defined(inline) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define INLINE inline +#define ALWAYS_INLINE __attribute__((always_inline)) +#elif defined(_MSC_VER) +#define INLINE __inline +#define ALWAYS_INLINE __forceinline +#else +#define INLINE __attribute__((unused)) +#define ALWAYS_INLINE +#endif + +#else +#define INLINE inline +#define ALWAYS_INLINE __attribute__((always_inline)) +#endif + +/* + * C90 does not have the restrict compiler directive yet. + * We don't use it in C90 builds. + */ +#if !defined(restrict) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define RESTRICT restrict +#else +#define RESTRICT +#endif + +#else + +#define RESTRICT restrict +#endif + +#define DEFAULT_ALIGN 32 +#if defined(_WIN32) +#define ALIGN __declspec(align(DEFAULT_ALIGN)) +#define asm __asm +#else +#define asm __asm__ +#define ALIGN __attribute__((aligned(DEFAULT_ALIGN))) #endif + +#endif /* MLKEM_NATIVE_SYS_H */ diff --git a/mlkem/sys/config.h b/mlkem/sys/config.h deleted file mode 100644 index 370a141a6..000000000 --- a/mlkem/sys/config.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024 The mlkem-native project authors - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CONFIG_H -#define CONFIG_H - -#include "cpucap.h" - -#if defined(MLKEM_USE_NATIVE) - -#if defined(SYS_AARCH64) -#define MLKEM_USE_NATIVE_AARCH64 -#endif /* SYS_AARCH64 */ - -#if defined(SYS_X86_64) -#define MLKEM_USE_NATIVE_X86_64 -#endif /* SYS_X86_64 */ - -#endif /* MLKEM_USE_NATIVE */ -#endif /* CONFIG_H */ diff --git a/mlkem/verify.c b/mlkem/verify.c index e616a8bab..b7078fcc1 100644 --- a/mlkem/verify.c +++ b/mlkem/verify.c @@ -13,7 +13,6 @@ volatile uint64_t ct_opt_blocker_u64 = 0; #else /* MLKEM_USE_ASM_VALUE_BARRIER */ -#include "params.h" #define empty_cu_verify MLKEM_NAMESPACE(empty_cu_verify) int empty_cu_verify; diff --git a/scripts/autogenerate_files.py b/scripts/autogenerate_files.py index a33d3cdfe..70d37d905 100644 --- a/scripts/autogenerate_files.py +++ b/scripts/autogenerate_files.py @@ -295,9 +295,13 @@ def gen_aarch64_mulcache_twiddles_twisted(): def gen_aarch64_fwd_ntt_zeta_file(dry_run=False): def gen(): yield from gen_header() - yield '#include "arith_native_aarch64.h"' + yield '#include "common.h"' + yield "" + yield "#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) || \\" + yield " defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT)" yield "" - yield "#ifdef MLKEM_USE_NATIVE_AARCH64" + yield "#include " + yield '#include "arith_native_aarch64.h"' yield "" yield "/*" yield " * Table of zeta values used in the AArch64 forward NTT" @@ -327,17 +331,17 @@ def gen(): yield from map(lambda t: str(t) + ",", gen_aarch64_mulcache_twiddles_twisted()) yield "};" yield "" - yield "#else /* MLKEM_USE_NATIVE_AARCH64 */" + yield "#else" yield '#include "params.h"' yield "" yield "/* Dummy declaration for compilers disliking empty compilation units */" yield "#define empty_cu_aarch64_zetas MLKEM_NAMESPACE(empty_cu_aarch64_zetas)" yield "int empty_cu_aarch64_zetas;" - yield "#endif /* MLKEM_USE_NATIVE_AARCH64 */" + yield "#endif" yield "" update_file( - "mlkem/native/aarch64/aarch64_zetas.c", "\n".join(gen()), dry_run=dry_run + "mlkem/native/aarch64/src/aarch64_zetas.c", "\n".join(gen()), dry_run=dry_run ) @@ -414,7 +418,9 @@ def gen(): yield from map(lambda t: str(t) + ",", gen_avx2_fwd_ntt_zetas()) yield "" - update_file("mlkem/native/x86_64/x86_64_zetas.i", "\n".join(gen()), dry_run=dry_run) + update_file( + "mlkem/native/x86_64/src/x86_64_zetas.i", "\n".join(gen()), dry_run=dry_run + ) def _main(): diff --git a/scripts/lib/mlkem_test.py b/scripts/lib/mlkem_test.py index 796c4953a..73d24122a 100644 --- a/scripts/lib/mlkem_test.py +++ b/scripts/lib/mlkem_test.py @@ -98,9 +98,7 @@ def dict2str(dict): f"{self.test_type}", ] + extra_make_args - make_envs = ( - {"CFLAGS": f"{self.cflags}"} if self.cflags is not None else {} - ) | ( + make_envs = ({"CFLAGS": self.cflags} if self.cflags is not None else {}) | ( {"ARCH_FLAGS": f"{self.arch_flags}"} if self.arch_flags is not None else {} ) extra_make_envs.update(make_envs) diff --git a/test/bench_components_mlkem.c b/test/bench_components_mlkem.c index c922cb76d..b3956171c 100644 --- a/test/bench_components_mlkem.c +++ b/test/bench_components_mlkem.c @@ -12,7 +12,7 @@ #include "randombytes.h" #include "rej_uniform.h" -#include "../mlkem/native/arith_native.h" +#include "../mlkem/arith_backend.h" #include "fips202.h" #include "indcpa.h" #include "keccakf1600.h" @@ -184,7 +184,7 @@ static int bench(void) BENCH("gen_matrix", gen_matrix((polyvec *)data0, (uint8_t *)data1, 0)) -#if defined(MLKEM_USE_NATIVE_AARCH64) +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN) BENCH("ntt-clean", ntt_asm_clean((int16_t *)data0, (int16_t *)data1, (int16_t *)data2)); BENCH("intt-clean", @@ -200,7 +200,9 @@ static int bench(void) polyvec_basemul_acc_montgomery_cached_asm_clean( (int16_t *)data0, (int16_t *)data1, (int16_t *)data2, (int16_t *)data3)); +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_CLEAN */ +#if defined(MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT) BENCH("ntt-opt", ntt_asm_opt((int16_t *)data0, (int16_t *)data1, (int16_t *)data2)); BENCH("intt-opt", @@ -214,7 +216,7 @@ static int bench(void) polyvec_basemul_acc_montgomery_cached_asm_opt( (int16_t *)data0, (int16_t *)data1, (int16_t *)data2, (int16_t *)data3)); -#endif +#endif /* MLKEM_NATIVE_ARITH_BACKEND_AARCH64_OPT */ return 0; } From 43982d5ac38f32102b27f20ca48cd8cb33708798 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 16 Dec 2024 20:14:52 +0000 Subject: [PATCH 2/3] Add example for custom config and custom FIPS-202 backend This commit adds another minimal example to `examples/`, demonstrating how to use a custom configuration file and a custom FIPS-202 backend. Signed-off-by: Hanno Becker --- .github/workflows/ci.yml | 3 + README.md | 2 +- examples/README.md | 5 + examples/custom_backend/Makefile | 64 ++++++ examples/custom_backend/README.md | 32 +++ examples/custom_backend/main.c | 69 ++++++ .../mlkem_native/custom_config.h | 113 ++++++++++ .../mlkem_native/fips202/LICENSE | 1 + .../mlkem_native/fips202/fips202.c | 1 + .../mlkem_native/fips202/fips202.h | 1 + .../mlkem_native/fips202/fips202_backend.h | 1 + .../mlkem_native/fips202/fips202x4.c | 1 + .../mlkem_native/fips202/fips202x4.h | 1 + .../mlkem_native/fips202/keccakf1600.c | 1 + .../mlkem_native/fips202/keccakf1600.h | 1 + .../mlkem_native/fips202/native/api.h | 1 + .../fips202/native/custom/custom.h | 25 +++ .../fips202/native/custom/src/LICENSE | 23 ++ .../fips202/native/custom/src/Makefile | 28 +++ .../fips202/native/custom/src/README.md | 63 ++++++ .../fips202/native/custom/src/custom_impl.h | 22 ++ .../fips202/native/custom/src/sha3.c | 197 ++++++++++++++++++ .../fips202/native/custom/src/sha3.h | 50 +++++ .../custom_backend/mlkem_native/mlkem/LICENSE | 1 + .../mlkem_native/mlkem/arith_backend.h | 1 + .../custom_backend/mlkem_native/mlkem/cbd.c | 1 + .../custom_backend/mlkem_native/mlkem/cbd.h | 1 + .../custom_backend/mlkem_native/mlkem/cbmc.h | 1 + .../mlkem_native/mlkem/common.h | 1 + .../mlkem_native/mlkem/config.h | 1 + .../custom_backend/mlkem_native/mlkem/debug | 1 + .../mlkem_native/mlkem/indcpa.c | 1 + .../mlkem_native/mlkem/indcpa.h | 1 + .../custom_backend/mlkem_native/mlkem/kem.c | 1 + .../custom_backend/mlkem_native/mlkem/kem.h | 1 + .../mlkem_native/mlkem/namespace.h | 1 + .../custom_backend/mlkem_native/mlkem/ntt.c | 1 + .../custom_backend/mlkem_native/mlkem/ntt.h | 1 + .../mlkem_native/mlkem/params.h | 1 + .../custom_backend/mlkem_native/mlkem/poly.c | 1 + .../custom_backend/mlkem_native/mlkem/poly.h | 1 + .../mlkem_native/mlkem/polyvec.c | 1 + .../mlkem_native/mlkem/polyvec.h | 1 + .../mlkem_native/mlkem/randombytes.h | 1 + .../mlkem_native/mlkem/reduce.h | 1 + .../mlkem_native/mlkem/rej_uniform.c | 1 + .../mlkem_native/mlkem/rej_uniform.h | 1 + .../mlkem_native/mlkem/symmetric.h | 1 + .../custom_backend/mlkem_native/mlkem/sys.h | 1 + .../mlkem_native/mlkem/verify.c | 1 + .../mlkem_native/mlkem/verify.h | 1 + .../custom_backend/mlkem_native/mlkem/zetas.c | 1 + .../test_only_rng/notrandombytes.c | 96 +++++++++ scripts/ci/lint | 2 +- 54 files changed, 830 insertions(+), 2 deletions(-) create mode 100644 examples/custom_backend/Makefile create mode 100644 examples/custom_backend/README.md create mode 100644 examples/custom_backend/main.c create mode 100644 examples/custom_backend/mlkem_native/custom_config.h create mode 120000 examples/custom_backend/mlkem_native/fips202/LICENSE create mode 120000 examples/custom_backend/mlkem_native/fips202/fips202.c create mode 120000 examples/custom_backend/mlkem_native/fips202/fips202.h create mode 120000 examples/custom_backend/mlkem_native/fips202/fips202_backend.h create mode 120000 examples/custom_backend/mlkem_native/fips202/fips202x4.c create mode 120000 examples/custom_backend/mlkem_native/fips202/fips202x4.h create mode 120000 examples/custom_backend/mlkem_native/fips202/keccakf1600.c create mode 120000 examples/custom_backend/mlkem_native/fips202/keccakf1600.h create mode 120000 examples/custom_backend/mlkem_native/fips202/native/api.h create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/custom.h create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/LICENSE create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/README.md create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/custom_impl.h create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c create mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/LICENSE create mode 120000 examples/custom_backend/mlkem_native/mlkem/arith_backend.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/cbd.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/cbd.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/cbmc.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/common.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/config.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/debug create mode 120000 examples/custom_backend/mlkem_native/mlkem/indcpa.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/indcpa.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/kem.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/kem.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/namespace.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/ntt.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/ntt.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/params.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/poly.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/poly.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/polyvec.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/polyvec.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/randombytes.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/reduce.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/rej_uniform.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/rej_uniform.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/symmetric.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/sys.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/verify.c create mode 120000 examples/custom_backend/mlkem_native/mlkem/verify.h create mode 120000 examples/custom_backend/mlkem_native/mlkem/zetas.c create mode 100644 examples/custom_backend/test_only_rng/notrandombytes.c diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0c7e65e7..e63ce068b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,6 +119,9 @@ jobs: - name: bring_your_own_fips202 run: | make run -C examples/bring_your_own_fips202 + - name: custom_backend + run: | + make run -C examples/custom_backend build_kat: needs: [quickcheck, quickcheck-windows] strategy: diff --git a/README.md b/README.md index f6f76f7b0..d43c2618a 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ in this repository is for experimental and development purposes only. If you pre ### Can I bring my own backend? Absolutely: You can add further backends for ML-KEM native arithmetic and/or for FIPS-202. Follow the existing backends -as templates. +as templates, or see [examples/custom_backend](examples/custom_backend) for a minimal example how to register a custom backend. ### Can I bring my own FIPS-202? diff --git a/examples/README.md b/examples/README.md index 3412042d1..ba73ec584 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,3 +12,8 @@ See [mlkem_native_as_code_package](mlkem_native_as_code_package). See [bring_your_own_fips202](bring_your_own_fips202) for an example of how to use mlkem-native with your own FIPS-202 implementation. + +## Using mlkem-native as a code package, custom config + custom FIPS-202 backend + +See [custom_backend](custom_backend) for an example of how to use mlkem-native with a custom configuration file and a +custom FIPS-202 backend. diff --git a/examples/custom_backend/Makefile b/examples/custom_backend/Makefile new file mode 100644 index 000000000..b1dad8549 --- /dev/null +++ b/examples/custom_backend/Makefile @@ -0,0 +1,64 @@ +# (SPDX-License-Identifier: CC-BY-4.0) + +.PHONY: build run clean + +# Part A: +# +# mlkem-native source and header files +# +# If you are not concerned about minimizing for a specific backend, +# you can just include _all_ source files into your build. +MLKEM_NATIVE_SOURCE=$(wildcard \ + mlkem_native/**/*.c \ + mlkem_native/**/*.c \ + mlkem_native/**/**/*.c \ + mlkem_native/**/**/**/*.c \ + mlkem_native/**/**/**/**/*.c) + +INC= +INC+=-Imlkem_native/ +INC+=-Imlkem_native/mlkem +INC+=-Imlkem_native/mlkem/native +INC+=-Imlkem_native/fips202 +INC+=-Imlkem_native/fips202/native + +# Part B: +# +# Random number generator +# +# !!! WARNING !!! +# +# The randombytes() implementation used here is for TESTING ONLY. +# You MUST NOT use this implementation outside of testing. +# +# !!! WARNING !!! +RNG_SOURCE=$(wildcard test_only_rng/*.c) + +# Part C: +# +# Your application source code +APP_SOURCE=$(wildcard *.c) + +ALL_SOURCE=$(MLKEM_NATIVE_SOURCE) $(RNG_SOURCE) $(APP_SOURCE) + +BUILD_DIR=build +BIN=test_binary + +CFLAGS=-DMLKEM_NATIVE_CONFIG_FILE="\"custom_config.h\"" + +BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN) + +$(BINARY_NAME_FULL): $(ALL_SOURCE) + echo "$@" + mkdir -p $(BUILD_DIR) + $(CC) $(CFLAGS) $(INC) $^ -o $@ + +all: run + +build: $(BINARY_NAME_FULL) + +run: $(BINARY_NAME_FULL) + ./$(BINARY_NAME_FULL) + +clean: + rm -rf $(BUILD_DIR) diff --git a/examples/custom_backend/README.md b/examples/custom_backend/README.md new file mode 100644 index 000000000..b4bfac358 --- /dev/null +++ b/examples/custom_backend/README.md @@ -0,0 +1,32 @@ +[//]: # (SPDX-License-Identifier: CC-BY-4.0) + +# Using a custom configuration and FIPS-202 backend + +This directory contains a minimal example for how to use mlkem-native as a code package, with a custom FIPS-202 +backend and a custom configuration. We use the [tiny_sha3](https://github.com/mjosaarinen/tiny_sha3/) by Markku-J. O. +Saarinen as an example. + +## Components + +An application using mlkem-native with a custom FIPS-202 backend and custom configuration needs the following: + +1. Arithmetic part of the mlkem-native source tree: [`mlkem/`](../../mlkem). In this example, we disable arithmetic + backends, hence it is safe to remove the entire `native` subfolder. +2. A secure pseudo random number generator, implementing [`randombytes.h`](../../mlkem/randombytes.h). **WARNING:** The + `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation outside of testing. +3. FIPS-202 part of the mlkem-native source tree, [`fips/`](../../fips202). If you only want to use your backend, + you can remove all existing backends; that's what this example does. +4. A custom FIPS-202 backend. In this example, the metadata file is + [custom.h](mlkem_native/fips202/native/custom/custom.h), the implementation shim is + [custom_impl.h](mlkem_native/fips202/native/custom/src/custom_impl.h), wrapping the + [sha3.c](mlkem_native/fips202/native/custom/src/sha3.c) and setting `MLKEM_USE_FIPS101_X1_NATIVE` to indicate that we + replace 1-fold Keccak-F1600. +5. Either modify the existing [config.h](mlkem_native/mlkem/config.h), or register a new config. In this example, we add + a new config [custom_config.h](mlkem_native/custom_config.h) and register it from the command line for + `-DMLKEM_NATIVE_CONFIG_FILE="custom_config.h"` -- no further changes to the build are needed. For the sake of + demonstration, we set a custom namespace. We set `MLKEM_NATIVE_FIPS202_BACKEND` to point to our custom FIPS-202 + backend, but leave `MLKEM_NATIVE_ARITH_BACKEND` undefined to indicate that we wish to use the C backend. + +## Usage + +Build this example with `make build`, run with `make run`. diff --git a/examples/custom_backend/main.c b/examples/custom_backend/main.c new file mode 100644 index 000000000..5dc1cc2a8 --- /dev/null +++ b/examples/custom_backend/main.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +const uint8_t expected_key[] = {0xe9, 0x13, 0x77, 0x84, 0x0e, 0x6b, 0x66, 0x94, + 0xea, 0xa9, 0xf0, 0x1c, 0x97, 0xff, 0x68, 0x87, + 0x4e, 0x8b, 0x0c, 0x52, 0x0b, 0x00, 0xc2, 0xcd, + 0xe3, 0x7c, 0x4f, 0xc2, 0x39, 0x62, 0x6e, 0x70}; + +int main(void) +{ + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + uint8_t ct[CRYPTO_CIPHERTEXTBYTES]; + uint8_t key_a[CRYPTO_BYTES]; + uint8_t key_b[CRYPTO_BYTES]; + + printf("Generating keypair ... "); + + /* Alice generates a public key */ + crypto_kem_keypair(pk, sk); + + printf("DONE\n"); + printf("Encaps... "); + + /* Bob derives a secret key and creates a response */ + crypto_kem_enc(ct, key_b, pk); + + printf("DONE\n"); + printf("Decaps... "); + + /* Alice uses Bobs response to get her shared key */ + crypto_kem_dec(key_a, ct, sk); + + printf("DONE\n"); + printf("Compare... "); + + if (memcmp(key_a, key_b, CRYPTO_BYTES)) + { + printf("ERROR: Mismatching keys\n"); + return 1; + } + + /* Check against hardcoded result to make sure that + * we integrated custom FIPS202 correctly */ + if (memcmp(key_a, expected_key, CRYPTO_BYTES) != 0) + { + printf("ERROR: Unexpected result\n"); + return 1; + } + + printf("OK\n"); + + printf("Shared secret: "); + { + int i; + for (i = 0; i < sizeof(key_a); i++) + printf("%02x", key_a[i]); + } + printf("\n"); + + return 0; +} diff --git a/examples/custom_backend/mlkem_native/custom_config.h b/examples/custom_backend/mlkem_native/custom_config.h new file mode 100644 index 000000000..ab40528f3 --- /dev/null +++ b/examples/custom_backend/mlkem_native/custom_config.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef MLKEM_NATIVE_CONFIG_H +#define MLKEM_NATIVE_CONFIG_H + +/****************************************************************************** + * Name: MLKEM_K + * + * Description: Determines the security level for ML-KEM + * - MLKEM_K=2 corresponds to ML-KEM-512 + * - MLKEM_K=3 corresponds to ML-KEM-768 + * - MLKEM_K=4 corresponds to ML-KEM-1024 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLKEM_K 3 /* We want MLKEM-768 */ + +/****************************************************************************** + * Name: MLKEM_NATIVE_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of mlkem/config.h. + * + * When you need to build mlkem-native in multiple configurations, + * this can be a convenient alternative to configuration via + * CFLAGS. + * + *****************************************************************************/ +/* No need to set this -- we _are_ already in a custom config */ +/* #define MLKEM_NATIVE_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLKEM_NAMESPACE + * _MLKEM_NAMESPACE + * + * Description: The macros to use to namespace global symbols + * from mlkem/. + *****************************************************************************/ +#define __CONC(a, b) a##b +#define CONC(a, b) __CONC(a, b) + +#define MLKEM_NAMESPACE(sym) CONC(CUSTOM_TINY_SHA3_, sym) +#define _MLKEM_NAMESPACE(sym) CONC(_CUSTOM_TINY_SHA3_, sym) + +/****************************************************************************** + * Name: FIPS202_NAMESPACE + * _FIPS202_NAMESPACE + * + * Description: The macros to use to namespace global symbols + * from fips202/. + *****************************************************************************/ +#define FIPS202_NAMESPACE(sym) CONC(CUSTOM_TINY_SHA3_, sym) +#define _FIPS202_NAMESPACE(sym) CONC(_CUSTOM_TINY_SHA3_, sym) + +/****************************************************************************** + * Name: MLKEM_USE_NATIVE + * + * Description: Determines whether a native backend should + * be used, if available. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLKEM_USE_NATIVE + +/****************************************************************************** + * Name: MLKEM_NATIVE_ARITH_BACKEND + * + * Description: The arithmetic backend to use. + * + * This must be the filename of an arithmetic + * backend. The backend is expected to define + * + * - MLKEM_NATIVE_ARITH_BACKEND_NAME + * + * The name of the backend as used in the default namespace. + * + * - MLKEM_NATIVE_ARITH_BACKEND_IMPL + * + * The filename of the implementation of the arithmetic backend. + * + * See the existing backends for more information. + * + *****************************************************************************/ +/* Let's pretend we don't want an arithmetic backend */ +/* #define MLKEM_NATIVE_ARITH_BACKEND "native/default.h" */ + +/****************************************************************************** + * Name: MLKEM_NATIVE_FIPS202_BACKEND + * + * Description: The FIPS-202 backend to use. + * + * This must be the filename of an FIPS-202 + * backend. The backend is expected to define + * + * - MLKEM_NATIVE_FIPS202_BACKEND_NAME + * + * The name of the backend as used in the default namespace. + * + * - MLKEM_NATIVE_FIPS202_BACKEND_IMPL + * + * The filename of the implementation of the FIPS-202 backend. + * + * See the existing backends for more information. + * + *****************************************************************************/ +#define MLKEM_NATIVE_FIPS202_BACKEND "fips202/native/custom/custom.h" + +#endif /* MLkEM_NATIVE_CONFIG_H */ diff --git a/examples/custom_backend/mlkem_native/fips202/LICENSE b/examples/custom_backend/mlkem_native/fips202/LICENSE new file mode 120000 index 000000000..bcebb16c1 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/LICENSE @@ -0,0 +1 @@ +../../../../fips202/LICENSE \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/fips202.c b/examples/custom_backend/mlkem_native/fips202/fips202.c new file mode 120000 index 000000000..34cf3813b --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/fips202.c @@ -0,0 +1 @@ +../../../../fips202/fips202.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/fips202.h b/examples/custom_backend/mlkem_native/fips202/fips202.h new file mode 120000 index 000000000..164a3b7b8 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/fips202.h @@ -0,0 +1 @@ +../../../../fips202/fips202.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/fips202_backend.h b/examples/custom_backend/mlkem_native/fips202/fips202_backend.h new file mode 120000 index 000000000..5397725dc --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/fips202_backend.h @@ -0,0 +1 @@ +../../../../fips202/fips202_backend.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/fips202x4.c b/examples/custom_backend/mlkem_native/fips202/fips202x4.c new file mode 120000 index 000000000..fd9ec60d1 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/fips202x4.c @@ -0,0 +1 @@ +../../../../fips202/fips202x4.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/fips202x4.h b/examples/custom_backend/mlkem_native/fips202/fips202x4.h new file mode 120000 index 000000000..4dc5c3b80 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/fips202x4.h @@ -0,0 +1 @@ +../../../../fips202/fips202x4.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/keccakf1600.c b/examples/custom_backend/mlkem_native/fips202/keccakf1600.c new file mode 120000 index 000000000..53a5e8617 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/keccakf1600.c @@ -0,0 +1 @@ +../../../../fips202/keccakf1600.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/keccakf1600.h b/examples/custom_backend/mlkem_native/fips202/keccakf1600.h new file mode 120000 index 000000000..fe6e51a4c --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/keccakf1600.h @@ -0,0 +1 @@ +../../../../fips202/keccakf1600.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/native/api.h b/examples/custom_backend/mlkem_native/fips202/native/api.h new file mode 120000 index 000000000..b255ddf09 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/api.h @@ -0,0 +1 @@ +../../../../../fips202/native/api.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/custom.h b/examples/custom_backend/mlkem_native/fips202/native/custom/custom.h new file mode 100644 index 000000000..2ef194461 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/custom.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default FIPS202 assembly profile for AArch64 systems */ + +#ifdef FIPS202_NATIVE_PROFILE_H +#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? +#else +#define FIPS202_NATIVE_PROFILE_H + +/* Identifier for this backend so that source and assembly files + * in the build can be appropriately guarded. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_CUSTOM_TINY_SHA3 + +#define MLKEM_NATIVE_FIPS202_BACKEND_NAME TINY_SHA3 + +/* Filename of the C backend implementation. + * This is not inlined here because this header is included in assembly + * files as well. */ +#define MLKEM_NATIVE_FIPS202_BACKEND_IMPL \ + "fips202/native/custom/src/custom_impl.h" + +#endif /* FIPS202_NATIVE_PROFILE_H */ diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/LICENSE b/examples/custom_backend/mlkem_native/fips202/native/custom/src/LICENSE new file mode 100644 index 000000000..35741e52a --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/LICENSE @@ -0,0 +1,23 @@ +[//]: # (SPDX-License-Identifier: CC-BY-4.0) + +The MIT License (MIT) + +Copyright (c) 2015 Markku-Juhani O. Saarinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile b/examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile new file mode 100644 index 000000000..e855f986f --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: MIT + +# Makefile +# 19-Nov-11 Markku-Juhani O. Saarinen + +BINARY = sha3test +OBJS = sha3.o main.o +DIST = tiny_sha3 + +CC = gcc +CFLAGS = -Wall -O3 +LIBS = +LDFLAGS = +INCLUDES = + +$(BINARY): $(OBJS) + $(CC) $(LDFLAGS) -o $(BINARY) $(OBJS) $(LIBS) + +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +clean: + rm -rf $(DIST)-*.txz $(OBJS) $(BINARY) *~ + +dist: clean + cd ..; \ + tar cfvJ $(DIST)/$(DIST)-`date -u "+%Y%m%d%H%M00"`.txz \ + $(DIST)/* diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/README.md b/examples/custom_backend/mlkem_native/fips202/native/custom/src/README.md new file mode 100644 index 000000000..66684bec2 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/README.md @@ -0,0 +1,63 @@ +[//]: # (SPDX-License-Identifier: MIT) + +# tiny_sha3 +Very small, readable implementation of the FIPS 202 and SHA3 hash function. +Public domain. + +### Updated 27-Dec-15: + +Added SHAKE128 and SHAKE256 code and test vectors. The code can actually do +a XOF of arbitrary size (like "SHAKE512"). + + +### Updated 03-Sep-15: + +Made the implementation portable. The API is now pretty much the +same that OpenSSL uses. + + +### Updated 07-Aug-15: + +Now that SHA3 spec is out, I've updated the package to match with the +new padding rules. There is literally one line difference between +Keccak 3.0 and SHA-3 implementations: + +``` + temp[inlen++] = 0x06; // XXX Padding Changed from Keccak 3.0 +``` + +The 0x06 constant there used to be 0x01. But this of course totally +breaks compatibility and test vectors had to be revised. + +SHA-3 Spec: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + +Cheers, +- markku + + +### Original README.TXT from 19-Nov-11: + +Hi. + +The SHA-3 competition is nearing it's end and I would personally like +to support Keccak as the winner. I have a PhD in hash function cryptanalysis +so don't take my word for it, go ahead and look into the code ! + +Since I couldn't find a *compact* and/or *readable* implementation of Keccak +anywhere, here's one I cooked up as a service to the curious. + +This implementation is intended for study of the algorithm, not for +production use. + +The code works correctly on 64-bit little-endian platforms with gcc. +Like your Linux box. The main.c module contains self-tests for all +officially supported hash sizes. + +If you're looking for production code, the official multi-megabyte package +covers everyting you could possibly need and too much much more: +http://keccak.noekeon.org/ + +Cheers, +- Markku 19-Nov-11 + +Dr. Markku-Juhani O. Saarinen diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/custom_impl.h b/examples/custom_backend/mlkem_native/fips202/native/custom/src/custom_impl.h new file mode 100644 index 000000000..242d6b7f4 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/custom_impl.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default FIPS202 assembly profile for AArch64 systems */ + +#ifdef FIPS202_NATIVE_PROFILE_IMPL_H +#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles? +#else +#define FIPS202_NATIVE_PROFILE_IMPL_H + +#include "sha3.h" + +/* Replace (single) Keccak-F1600 by tiny-SHA3's */ +#define MLKEM_USE_FIPS202_X1_NATIVE +static INLINE void keccak_f1600_x1_native(uint64_t *state) +{ + sha3_keccakf(state); +} + +#endif /* FIPS202_NATIVE_PROFILE_H */ diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c new file mode 100644 index 000000000..c21684ae5 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: MIT +// +// sha3.c +// 19-Nov-11 Markku-Juhani O. Saarinen + +// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" +// Revised 03-Sep-15 for portability + OpenSSL - style API + +#include "sha3.h" + +// update the state with given number of rounds + +void sha3_keccakf(uint64_t st[25]) +{ + // constants + const uint64_t keccakf_rndc[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}; + const int keccakf_rotc[24] = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44}; + const int keccakf_piln[24] = {10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1}; + + // variables + int i, j, r; + uint64_t t, bc[5]; + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + uint8_t *v; + + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) + { + v = (uint8_t *)&st[i]; + st[i] = ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) | + (((uint64_t)v[2]) << 16) | (((uint64_t)v[3]) << 24) | + (((uint64_t)v[4]) << 32) | (((uint64_t)v[5]) << 40) | + (((uint64_t)v[6]) << 48) | (((uint64_t)v[7]) << 56); + } +#endif + + // actual iteration + for (r = 0; r < KECCAKF_ROUNDS; r++) + { + // Theta + for (i = 0; i < 5; i++) + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + + for (i = 0; i < 5; i++) + { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + st[j + i] ^= t; + } + + // Rho Pi + t = st[1]; + for (i = 0; i < 24; i++) + { + j = keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, keccakf_rotc[i]); + t = bc[0]; + } + + // Chi + for (j = 0; j < 25; j += 5) + { + for (i = 0; i < 5; i++) + bc[i] = st[j + i]; + for (i = 0; i < 5; i++) + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + + // Iota + st[0] ^= keccakf_rndc[r]; + } + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) + { + v = (uint8_t *)&st[i]; + t = st[i]; + v[0] = t & 0xFF; + v[1] = (t >> 8) & 0xFF; + v[2] = (t >> 16) & 0xFF; + v[3] = (t >> 24) & 0xFF; + v[4] = (t >> 32) & 0xFF; + v[5] = (t >> 40) & 0xFF; + v[6] = (t >> 48) & 0xFF; + v[7] = (t >> 56) & 0xFF; + } +#endif +} + +// Initialize the context for SHA3 + +int sha3_init(sha3_ctx_t *c, int mdlen) +{ + int i; + + for (i = 0; i < 25; i++) + c->st.q[i] = 0; + c->mdlen = mdlen; + c->rsiz = 200 - 2 * mdlen; + c->pt = 0; + + return 1; +} + +// update state with more data + +int sha3_update(sha3_ctx_t *c, const void *data, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) + { + c->st.b[j++] ^= ((const uint8_t *)data)[i]; + if (j >= c->rsiz) + { + sha3_keccakf(c->st.q); + j = 0; + } + } + c->pt = j; + + return 1; +} + +// finalize and output a hash + +int sha3_final(void *md, sha3_ctx_t *c) +{ + int i; + + c->st.b[c->pt] ^= 0x06; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + + for (i = 0; i < c->mdlen; i++) + { + ((uint8_t *)md)[i] = c->st.b[i]; + } + + return 1; +} + +// compute a SHA-3 hash (md) of given byte length from "in" + +void *sha3(const void *in, size_t inlen, void *md, int mdlen) +{ + sha3_ctx_t sha3; + + sha3_init(&sha3, mdlen); + sha3_update(&sha3, in, inlen); + sha3_final(md, &sha3); + + return md; +} + +// SHAKE128 and SHAKE256 extensible-output functionality + +void shake_xof(sha3_ctx_t *c) +{ + c->st.b[c->pt] ^= 0x1F; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + c->pt = 0; +} + +void shake_out(sha3_ctx_t *c, void *out, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) + { + if (j >= c->rsiz) + { + sha3_keccakf(c->st.q); + j = 0; + } + ((uint8_t *)out)[i] = c->st.b[j++]; + } + c->pt = j; +} diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.h b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.h new file mode 100644 index 000000000..fb5276059 --- /dev/null +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +// +// sha3.h +// 19-Nov-11 Markku-Juhani O. Saarinen + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +// state context +typedef struct +{ + union + { // state: + uint8_t b[200]; // 8-bit bytes + uint64_t q[25]; // 64-bit words + } st; + int pt, rsiz, mdlen; // these don't overflow +} sha3_ctx_t; + +// Compression function. +void sha3_keccakf(uint64_t st[25]); + +// OpenSSL - like interfece +int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes +int sha3_update(sha3_ctx_t *c, const void *data, size_t len); +int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md + +// compute a sha3 hash (md) of given byte length from "in" +void *sha3(const void *in, size_t inlen, void *md, int mdlen); + +// SHAKE128 and SHAKE256 extensible-output functions +#define shake128_init(c) sha3_init(c, 16) +#define shake256_init(c) sha3_init(c, 32) +#define shake_update sha3_update + +void shake_xof(sha3_ctx_t *c); +void shake_out(sha3_ctx_t *c, void *out, size_t len); + +#endif diff --git a/examples/custom_backend/mlkem_native/mlkem/LICENSE b/examples/custom_backend/mlkem_native/mlkem/LICENSE new file mode 120000 index 000000000..8fae44d93 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/LICENSE @@ -0,0 +1 @@ +../../../../mlkem/LICENSE \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/arith_backend.h b/examples/custom_backend/mlkem_native/mlkem/arith_backend.h new file mode 120000 index 000000000..c7abf8ecd --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/arith_backend.h @@ -0,0 +1 @@ +../../../../mlkem/arith_backend.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/cbd.c b/examples/custom_backend/mlkem_native/mlkem/cbd.c new file mode 120000 index 000000000..66131480c --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/cbd.c @@ -0,0 +1 @@ +../../../../mlkem/cbd.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/cbd.h b/examples/custom_backend/mlkem_native/mlkem/cbd.h new file mode 120000 index 000000000..941b8bd44 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/cbd.h @@ -0,0 +1 @@ +../../../../mlkem/cbd.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/cbmc.h b/examples/custom_backend/mlkem_native/mlkem/cbmc.h new file mode 120000 index 000000000..1d7ad6bf2 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/cbmc.h @@ -0,0 +1 @@ +../../../../mlkem/cbmc.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/common.h b/examples/custom_backend/mlkem_native/mlkem/common.h new file mode 120000 index 000000000..f6ec75f66 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/common.h @@ -0,0 +1 @@ +../../../../mlkem/common.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/config.h b/examples/custom_backend/mlkem_native/mlkem/config.h new file mode 120000 index 000000000..a71bed830 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/config.h @@ -0,0 +1 @@ +../../../../mlkem/config.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/debug b/examples/custom_backend/mlkem_native/mlkem/debug new file mode 120000 index 000000000..cd511d740 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/debug @@ -0,0 +1 @@ +../../../../mlkem/debug \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/indcpa.c b/examples/custom_backend/mlkem_native/mlkem/indcpa.c new file mode 120000 index 000000000..56b7fc666 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/indcpa.c @@ -0,0 +1 @@ +../../../../mlkem/indcpa.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/indcpa.h b/examples/custom_backend/mlkem_native/mlkem/indcpa.h new file mode 120000 index 000000000..6bec2894b --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/indcpa.h @@ -0,0 +1 @@ +../../../../mlkem/indcpa.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/kem.c b/examples/custom_backend/mlkem_native/mlkem/kem.c new file mode 120000 index 000000000..2677344d2 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/kem.c @@ -0,0 +1 @@ +../../../../mlkem/kem.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/kem.h b/examples/custom_backend/mlkem_native/mlkem/kem.h new file mode 120000 index 000000000..6f74e1af6 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/kem.h @@ -0,0 +1 @@ +../../../../mlkem/kem.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/namespace.h b/examples/custom_backend/mlkem_native/mlkem/namespace.h new file mode 120000 index 000000000..c41101c01 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/namespace.h @@ -0,0 +1 @@ +../../../../mlkem/namespace.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/ntt.c b/examples/custom_backend/mlkem_native/mlkem/ntt.c new file mode 120000 index 000000000..693bc94f2 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/ntt.c @@ -0,0 +1 @@ +../../../../mlkem/ntt.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/ntt.h b/examples/custom_backend/mlkem_native/mlkem/ntt.h new file mode 120000 index 000000000..5ea1982c5 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/ntt.h @@ -0,0 +1 @@ +../../../../mlkem/ntt.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/params.h b/examples/custom_backend/mlkem_native/mlkem/params.h new file mode 120000 index 000000000..f9fc45bfb --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/params.h @@ -0,0 +1 @@ +../../../../mlkem/params.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/poly.c b/examples/custom_backend/mlkem_native/mlkem/poly.c new file mode 120000 index 000000000..8f37481c9 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/poly.c @@ -0,0 +1 @@ +../../../../mlkem/poly.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/poly.h b/examples/custom_backend/mlkem_native/mlkem/poly.h new file mode 120000 index 000000000..6aa17ed35 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/poly.h @@ -0,0 +1 @@ +../../../../mlkem/poly.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/polyvec.c b/examples/custom_backend/mlkem_native/mlkem/polyvec.c new file mode 120000 index 000000000..358c967ff --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/polyvec.c @@ -0,0 +1 @@ +../../../../mlkem/polyvec.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/polyvec.h b/examples/custom_backend/mlkem_native/mlkem/polyvec.h new file mode 120000 index 000000000..b3a001d95 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/polyvec.h @@ -0,0 +1 @@ +../../../../mlkem/polyvec.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/randombytes.h b/examples/custom_backend/mlkem_native/mlkem/randombytes.h new file mode 120000 index 000000000..d1b4aeb9e --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/randombytes.h @@ -0,0 +1 @@ +../../../../mlkem/randombytes.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/reduce.h b/examples/custom_backend/mlkem_native/mlkem/reduce.h new file mode 120000 index 000000000..6b2408820 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/reduce.h @@ -0,0 +1 @@ +../../../../mlkem/reduce.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/rej_uniform.c b/examples/custom_backend/mlkem_native/mlkem/rej_uniform.c new file mode 120000 index 000000000..bcc45b521 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/rej_uniform.c @@ -0,0 +1 @@ +../../../../mlkem/rej_uniform.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/rej_uniform.h b/examples/custom_backend/mlkem_native/mlkem/rej_uniform.h new file mode 120000 index 000000000..1d2f26cdb --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/rej_uniform.h @@ -0,0 +1 @@ +../../../../mlkem/rej_uniform.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/symmetric.h b/examples/custom_backend/mlkem_native/mlkem/symmetric.h new file mode 120000 index 000000000..a44e26f71 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/symmetric.h @@ -0,0 +1 @@ +../../../../mlkem/symmetric.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/sys.h b/examples/custom_backend/mlkem_native/mlkem/sys.h new file mode 120000 index 000000000..c6b25c7f2 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/sys.h @@ -0,0 +1 @@ +../../../../mlkem/sys.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/verify.c b/examples/custom_backend/mlkem_native/mlkem/verify.c new file mode 120000 index 000000000..d49e9df42 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/verify.c @@ -0,0 +1 @@ +../../../../mlkem/verify.c \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/verify.h b/examples/custom_backend/mlkem_native/mlkem/verify.h new file mode 120000 index 000000000..82ae31329 --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/verify.h @@ -0,0 +1 @@ +../../../../mlkem/verify.h \ No newline at end of file diff --git a/examples/custom_backend/mlkem_native/mlkem/zetas.c b/examples/custom_backend/mlkem_native/mlkem/zetas.c new file mode 120000 index 000000000..4e1a91dda --- /dev/null +++ b/examples/custom_backend/mlkem_native/mlkem/zetas.c @@ -0,0 +1 @@ +../../../../mlkem/zetas.c \ No newline at end of file diff --git a/examples/custom_backend/test_only_rng/notrandombytes.c b/examples/custom_backend/test_only_rng/notrandombytes.c new file mode 100644 index 000000000..93807622d --- /dev/null +++ b/examples/custom_backend/test_only_rng/notrandombytes.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 The mlkem-native project authors + * SPDX-License-Identifier: LicenseRef-PD-hp OR CC0-1.0 OR 0BSD OR MIT-0 OR MI + * Based on https://cr.yp.to/papers.html#surf by Daniel. J. Bernstein + */ + +/** + * WARNING + * + * The randombytes() implementation in this file is for TESTING ONLY. + * You MUST NOT use this implementation outside of testing. + * + */ + +#warning !!! WARNING !!! +#warning THIS BUILD IS USING A TEST-ONLY RANDOM NUMBER GENERATOR WHICH MUST NOT BE USED IN PRODUCTION + +#include +#include "randombytes.h" + +static uint32_t seed[32] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, + 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5}; +static uint32_t in[12]; +static uint32_t out[8]; +static int32_t outleft = 0; + +#define ROTATE(x, b) (((x) << (b)) | ((x) >> (32 - (b)))) +#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x, b)); + +static void surf(void) +{ + uint32_t t[12]; + uint32_t x; + uint32_t sum = 0; + int32_t r; + int32_t i; + int32_t loop; + + for (i = 0; i < 12; ++i) + { + t[i] = in[i] ^ seed[12 + i]; + } + for (i = 0; i < 8; ++i) + { + out[i] = seed[24 + i]; + } + x = t[11]; + for (loop = 0; loop < 2; ++loop) + { + for (r = 0; r < 16; ++r) + { + sum += 0x9e3779b9; + MUSH(0, 5) + MUSH(1, 7) + MUSH(2, 9) + MUSH(3, 13) + MUSH(4, 5) + MUSH(5, 7) + MUSH(6, 9) + MUSH(7, 13) + MUSH(8, 5) + MUSH(9, 7) + MUSH(10, 9) + MUSH(11, 13) + } + for (i = 0; i < 8; ++i) + { + out[i] ^= t[i + 4]; + } + } +} + +void randombytes(uint8_t *buf, size_t n) +{ + while (n > 0) + { + if (!outleft) + { + if (!++in[0]) + { + if (!++in[1]) + { + if (!++in[2]) + { + ++in[3]; + } + } + } + surf(); + outleft = 8; + } + *buf = (uint8_t)out[--outleft]; + ++buf; + --n; + } +} diff --git a/scripts/ci/lint b/scripts/ci/lint index 406f00526..879ad13b2 100755 --- a/scripts/ci/lint +++ b/scripts/ci/lint @@ -85,7 +85,7 @@ check-spdx() success=false fi done - for file in $(git ls-files -- "*.[chsS]" "*.py" ":/!cbmc/*.py" ":/!examples/bring_your_own_fips202/custom_fips202/tiny_sha3/*"); do + for file in $(git ls-files -- "*.[chsS]" "*.py" ":/!cbmc/*.py" ":/!examples/bring_your_own_fips202/custom_fips202/tiny_sha3/*" ":/!examples/custom_backend/mlkem_native/fips202/native/custom/src/*"); do # Ignore symlinks if [[ ! -L $file && $(grep "Copyright (c) 2024 The mlkem-native project authors" $file | wc -l) == 0 ]]; then echo "::error file=$file,line=${line:-1},title=Missing copyright header error::$file is missing copyright header" From d170c4e8752182c01e41753838855c8af9ca35d0 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 17 Dec 2024 06:11:29 +0000 Subject: [PATCH 3/3] Examples: Remove unnecessary tiny_sha3 Makefile + main Signed-off-by: Hanno Becker --- .../custom_fips202/tiny_sha3/Makefile | 28 --- .../custom_fips202/tiny_sha3/main.c | 196 ------------------ .../fips202/native/custom/src/Makefile | 28 --- 3 files changed, 252 deletions(-) delete mode 100644 examples/bring_your_own_fips202/custom_fips202/tiny_sha3/Makefile delete mode 100644 examples/bring_your_own_fips202/custom_fips202/tiny_sha3/main.c delete mode 100644 examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile diff --git a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/Makefile b/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/Makefile deleted file mode 100644 index e855f986f..000000000 --- a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: MIT - -# Makefile -# 19-Nov-11 Markku-Juhani O. Saarinen - -BINARY = sha3test -OBJS = sha3.o main.o -DIST = tiny_sha3 - -CC = gcc -CFLAGS = -Wall -O3 -LIBS = -LDFLAGS = -INCLUDES = - -$(BINARY): $(OBJS) - $(CC) $(LDFLAGS) -o $(BINARY) $(OBJS) $(LIBS) - -.c.o: - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -clean: - rm -rf $(DIST)-*.txz $(OBJS) $(BINARY) *~ - -dist: clean - cd ..; \ - tar cfvJ $(DIST)/$(DIST)-`date -u "+%Y%m%d%H%M00"`.txz \ - $(DIST)/* diff --git a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/main.c b/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/main.c deleted file mode 100644 index b5fbbab6c..000000000 --- a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/main.c +++ /dev/null @@ -1,196 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// main.c -// 19-Nov-11 Markku-Juhani O. Saarinen - -#include -#include -#include -#include "sha3.h" - -// read a hex string, return byte length or -1 on error. - -static int test_hexdigit(char ch) -{ - if (ch >= '0' && ch <= '9') - return ch - '0'; - if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - return -1; -} - -static int test_readhex(uint8_t *buf, const char *str, int maxbytes) -{ - int i, h, l; - - for (i = 0; i < maxbytes; i++) - { - h = test_hexdigit(str[2 * i]); - if (h < 0) - return i; - l = test_hexdigit(str[2 * i + 1]); - if (l < 0) - return i; - buf[i] = (h << 4) + l; - } - - return i; -} - -// returns zero on success, nonzero + stderr messages on failure - -int test_sha3() -{ - // message / digest pairs, lifted from ShortMsgKAT_SHA3-xxx.txt files - // in the official package: https://github.com/gvanas/KeccakCodePackage - - const char *testvec[][2] = { - {// SHA3-224, corner case with 0-length message - "", "6B4E03423667DBB73B6E15454F0EB1ABD4597F9A1B078E3F5B5A6BC7"}, - {// SHA3-256, short message - "9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10", - "2F1A5F7159E34EA19CDDC70EBF9B81F1A66DB40615D7EAD3CC1F1B954D82A3AF"}, - {// SHA3-384, exact block size - "E35780EB9799AD4C77535D4DDB683CF33EF367715327CF4C4A58ED9CBDCDD486" - "F669F80189D549A9364FA82A51A52654EC721BB3AAB95DCEB4A86A6AFA93826D" - "B923517E928F33E3FBA850D45660EF83B9876ACCAFA2A9987A254B137C6E140A" - "21691E1069413848", - "D1C0FA85C8D183BEFF99AD9D752B263E286B477F79F0710B0103170173978133" - "44B99DAF3BB7B1BC5E8D722BAC85943A"}, - {// SHA3-512, multiblock message - "3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5" - "623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A" - "15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0" - "A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764" - "B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43" - "C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D" - "817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E08" - "5172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1", - "6E8B8BD195BDD560689AF2348BDC74AB7CD05ED8B9A57711E9BE71E9726FDA45" - "91FEE12205EDACAF82FFBBAF16DFF9E702A708862080166C2FF6BA379BC7FFC2"}}; - - int i, fails, msg_len, sha_len; - uint8_t sha[64], buf[64], msg[256]; - - fails = 0; - for (i = 0; i < 4; i++) - { - memset(sha, 0, sizeof(sha)); - memset(buf, 0, sizeof(buf)); - memset(msg, 0, sizeof(msg)); - - msg_len = test_readhex(msg, testvec[i][0], sizeof(msg)); - sha_len = test_readhex(sha, testvec[i][1], sizeof(sha)); - - sha3(msg, msg_len, buf, sha_len); - - if (memcmp(sha, buf, sha_len) != 0) - { - fprintf(stderr, "[%d] SHA3-%d, len %d test FAILED.\n", i, sha_len * 8, - msg_len); - fails++; - } - } - - return fails; -} - -// test for SHAKE128 and SHAKE256 - -int test_shake() -{ - // Test vectors have bytes 480..511 of XOF output for given inputs. - // From http://csrc.nist.gov/groups/ST/toolkit/examples.html#aHashing - - const char *testhex[4] = { - // SHAKE128, message of length 0 - "43E41B45A653F2A5C4492C1ADD544512DDA2529833462B71A41A45BE97290B6F", - // SHAKE256, message of length 0 - "AB0BAE316339894304E35877B0C28A9B1FD166C796B9CC258A064A8F57E27F2A", - // SHAKE128, 1600-bit test pattern - "44C9FB359FD56AC0A9A75A743CFF6862F17D7259AB075216C0699511643B6439", - // SHAKE256, 1600-bit test pattern - "6A1A9D7846436E4DCA5728B6F760EEF0CA92BF0BE5615E96959D767197A0BEEB"}; - - int i, j, fails; - sha3_ctx_t sha3; - uint8_t buf[32], ref[32]; - - fails = 0; - - for (i = 0; i < 4; i++) - { - if ((i & 1) == 0) - { // test each twice - shake128_init(&sha3); - } - else - { - shake256_init(&sha3); - } - - if (i >= 2) - { // 1600-bit test pattern - memset(buf, 0xA3, 20); - for (j = 0; j < 200; j += 20) - shake_update(&sha3, buf, 20); - } - - shake_xof(&sha3); // switch to extensible output - - for (j = 0; j < 512; j += 32) // output. discard bytes 0..479 - shake_out(&sha3, buf, 32); - - // compare to reference - test_readhex(ref, testhex[i], sizeof(ref)); - if (memcmp(buf, ref, 32) != 0) - { - fprintf(stderr, "[%d] SHAKE%d, len %d test FAILED.\n", i, - i & 1 ? 256 : 128, i >= 2 ? 1600 : 0); - fails++; - } - } - - return fails; -} - -// test speed of the comp - -void test_speed() -{ - int i; - uint64_t st[25], x, n; - clock_t bg, us; - - for (i = 0; i < 25; i++) - st[i] = i; - - bg = clock(); - n = 0; - do - { - for (i = 0; i < 100000; i++) - sha3_keccakf(st); - n += i; - us = clock() - bg; - } while (us < 3 * CLOCKS_PER_SEC); - - x = 0; - for (i = 0; i < 25; i++) - x += st[i]; - - printf("(%016lX) %.3f Keccak-p[1600,24] / Second.\n", (unsigned long)x, - (CLOCKS_PER_SEC * ((double)n)) / ((double)us)); -} - -// main -int main(int argc, char **argv) -{ - if (test_sha3() == 0 && test_shake() == 0) - printf("FIPS 202 / SHA3, SHAKE128, SHAKE256 Self-Tests OK!\n"); - test_speed(); - - return 0; -} diff --git a/examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile b/examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile deleted file mode 100644 index e855f986f..000000000 --- a/examples/custom_backend/mlkem_native/fips202/native/custom/src/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: MIT - -# Makefile -# 19-Nov-11 Markku-Juhani O. Saarinen - -BINARY = sha3test -OBJS = sha3.o main.o -DIST = tiny_sha3 - -CC = gcc -CFLAGS = -Wall -O3 -LIBS = -LDFLAGS = -INCLUDES = - -$(BINARY): $(OBJS) - $(CC) $(LDFLAGS) -o $(BINARY) $(OBJS) $(LIBS) - -.c.o: - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -clean: - rm -rf $(DIST)-*.txz $(OBJS) $(BINARY) *~ - -dist: clean - cd ..; \ - tar cfvJ $(DIST)/$(DIST)-`date -u "+%Y%m%d%H%M00"`.txz \ - $(DIST)/*