From fc1531732a3dada6b140683d7aa005983ce68714 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:35:44 +0000 Subject: [PATCH 01/13] Examples: Remove default FIPS202 from bring-your-own-FIPS202 This example is meant to demonstrate how to use mlkem-native with a custom FIPS202 impleemntation, so it makes more sense to not even include the default FIPS202 implementation. Signed-off-by: Hanno Becker --- examples/bring_your_own_fips202/Makefile | 13 ++++++------- .../bring_your_own_fips202/custom_fips202/fips202.h | 2 +- examples/bring_your_own_fips202/main.c | 2 +- .../bring_your_own_fips202/mlkem_native/LICENSE | 1 + examples/bring_your_own_fips202/mlkem_native/api.h | 1 + .../mlkem_native/arith_backend.h | 1 + examples/bring_your_own_fips202/mlkem_native/cbd.c | 1 + examples/bring_your_own_fips202/mlkem_native/cbd.h | 1 + examples/bring_your_own_fips202/mlkem_native/cbmc.h | 1 + .../bring_your_own_fips202/mlkem_native/common.h | 1 + .../bring_your_own_fips202/mlkem_native/config.h | 1 + examples/bring_your_own_fips202/mlkem_native/debug | 1 + .../bring_your_own_fips202/mlkem_native/indcpa.c | 1 + .../bring_your_own_fips202/mlkem_native/indcpa.h | 1 + examples/bring_your_own_fips202/mlkem_native/kem.c | 1 + examples/bring_your_own_fips202/mlkem_native/kem.h | 1 + examples/bring_your_own_fips202/mlkem_native/mlkem | 1 - .../mlkem_native/mlkem_native.h | 1 + examples/bring_your_own_fips202/mlkem_native/native | 1 + examples/bring_your_own_fips202/mlkem_native/ntt.c | 1 + examples/bring_your_own_fips202/mlkem_native/ntt.h | 1 + .../bring_your_own_fips202/mlkem_native/params.h | 1 + examples/bring_your_own_fips202/mlkem_native/poly.c | 1 + examples/bring_your_own_fips202/mlkem_native/poly.h | 1 + .../bring_your_own_fips202/mlkem_native/polyvec.c | 1 + .../bring_your_own_fips202/mlkem_native/polyvec.h | 1 + .../mlkem_native/randombytes.h | 1 + .../bring_your_own_fips202/mlkem_native/reduce.h | 1 + .../mlkem_native/rej_uniform.c | 1 + .../mlkem_native/rej_uniform.h | 1 + .../bring_your_own_fips202/mlkem_native/symmetric.h | 1 + examples/bring_your_own_fips202/mlkem_native/sys.h | 1 + .../bring_your_own_fips202/mlkem_native/verify.c | 1 + .../bring_your_own_fips202/mlkem_native/verify.h | 1 + .../bring_your_own_fips202/mlkem_native/zetas.c | 1 + 35 files changed, 39 insertions(+), 10 deletions(-) create mode 120000 examples/bring_your_own_fips202/mlkem_native/LICENSE create mode 120000 examples/bring_your_own_fips202/mlkem_native/api.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/arith_backend.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/cbd.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/cbd.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/cbmc.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/common.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/config.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/debug create mode 120000 examples/bring_your_own_fips202/mlkem_native/indcpa.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/indcpa.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/kem.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/kem.h delete mode 120000 examples/bring_your_own_fips202/mlkem_native/mlkem create mode 120000 examples/bring_your_own_fips202/mlkem_native/mlkem_native.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/native create mode 120000 examples/bring_your_own_fips202/mlkem_native/ntt.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/ntt.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/params.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/poly.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/poly.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/polyvec.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/polyvec.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/randombytes.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/reduce.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/rej_uniform.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/rej_uniform.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/symmetric.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/sys.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/verify.c create mode 120000 examples/bring_your_own_fips202/mlkem_native/verify.h create mode 120000 examples/bring_your_own_fips202/mlkem_native/zetas.c diff --git a/examples/bring_your_own_fips202/Makefile b/examples/bring_your_own_fips202/Makefile index e4152b7b0..83d9e0079 100644 --- a/examples/bring_your_own_fips202/Makefile +++ b/examples/bring_your_own_fips202/Makefile @@ -9,16 +9,15 @@ # 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 \ - mlkem_native/**/**/**/*.c \ - mlkem_native/**/**/**/**/*.c) + mlkem_native/**/**/*.c \ + mlkem_native/**/**/**/*.c) INC= -INC+=-Imlkem_native/mlkem -INC+=-Imlkem_native/mlkem -INC+=-Imlkem_native/mlkem/native +INC+=-Imlkem_native/ +INC+=-Imlkem_native/native # 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 4bebebeb0..4966a0fad 100644 --- a/examples/bring_your_own_fips202/custom_fips202/fips202.h +++ b/examples/bring_your_own_fips202/custom_fips202/fips202.h @@ -77,7 +77,7 @@ static INLINE void shake128_squeezeblocks(uint8_t *output, size_t nblocks, /* Free the state */ #define shake128_release FIPS202_NAMESPACE(shake128_release) -static INLINE void shake128_release(shake128ctx *state) {} +static INLINE void shake128_release(shake128ctx *state) { ((void)state); } /* One-stop SHAKE256 call. Aliasing between input and * output is not permitted */ diff --git a/examples/bring_your_own_fips202/main.c b/examples/bring_your_own_fips202/main.c index 1ea54442c..386467cc2 100644 --- a/examples/bring_your_own_fips202/main.c +++ b/examples/bring_your_own_fips202/main.c @@ -59,7 +59,7 @@ int main(void) printf("Shared secret: "); { - int i; + size_t i; for (i = 0; i < sizeof(key_a); i++) printf("%02x", key_a[i]); } diff --git a/examples/bring_your_own_fips202/mlkem_native/LICENSE b/examples/bring_your_own_fips202/mlkem_native/LICENSE new file mode 120000 index 000000000..ed7b0a9a3 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/LICENSE @@ -0,0 +1 @@ +../../../mlkem/LICENSE \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/api.h b/examples/bring_your_own_fips202/mlkem_native/api.h new file mode 120000 index 000000000..4d51140df --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/api.h @@ -0,0 +1 @@ +../../../mlkem/api.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/arith_backend.h b/examples/bring_your_own_fips202/mlkem_native/arith_backend.h new file mode 120000 index 000000000..ceb46c58c --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/arith_backend.h @@ -0,0 +1 @@ +../../../mlkem/arith_backend.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/cbd.c b/examples/bring_your_own_fips202/mlkem_native/cbd.c new file mode 120000 index 000000000..4eddab21c --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/cbd.c @@ -0,0 +1 @@ +../../../mlkem/cbd.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/cbd.h b/examples/bring_your_own_fips202/mlkem_native/cbd.h new file mode 120000 index 000000000..02d999ea6 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/cbd.h @@ -0,0 +1 @@ +../../../mlkem/cbd.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/cbmc.h b/examples/bring_your_own_fips202/mlkem_native/cbmc.h new file mode 120000 index 000000000..f2593012b --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/cbmc.h @@ -0,0 +1 @@ +../../../mlkem/cbmc.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/common.h b/examples/bring_your_own_fips202/mlkem_native/common.h new file mode 120000 index 000000000..d5bee1a84 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/common.h @@ -0,0 +1 @@ +../../../mlkem/common.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/config.h b/examples/bring_your_own_fips202/mlkem_native/config.h new file mode 120000 index 000000000..3a44022aa --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/config.h @@ -0,0 +1 @@ +../../../mlkem/config.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/debug b/examples/bring_your_own_fips202/mlkem_native/debug new file mode 120000 index 000000000..71404afb6 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/debug @@ -0,0 +1 @@ +../../../mlkem/debug \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/indcpa.c b/examples/bring_your_own_fips202/mlkem_native/indcpa.c new file mode 120000 index 000000000..25ac06b89 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/indcpa.c @@ -0,0 +1 @@ +../../../mlkem/indcpa.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/indcpa.h b/examples/bring_your_own_fips202/mlkem_native/indcpa.h new file mode 120000 index 000000000..7e7df1876 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/indcpa.h @@ -0,0 +1 @@ +../../../mlkem/indcpa.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/kem.c b/examples/bring_your_own_fips202/mlkem_native/kem.c new file mode 120000 index 000000000..9d2bb59ed --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/kem.c @@ -0,0 +1 @@ +../../../mlkem/kem.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/kem.h b/examples/bring_your_own_fips202/mlkem_native/kem.h new file mode 120000 index 000000000..6ffece0a0 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/kem.h @@ -0,0 +1 @@ +../../../mlkem/kem.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/mlkem b/examples/bring_your_own_fips202/mlkem_native/mlkem deleted file mode 120000 index f4ec7bdb2..000000000 --- a/examples/bring_your_own_fips202/mlkem_native/mlkem +++ /dev/null @@ -1 +0,0 @@ -../../../mlkem \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/mlkem_native.h b/examples/bring_your_own_fips202/mlkem_native/mlkem_native.h new file mode 120000 index 000000000..dd32c33bb --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/mlkem_native.h @@ -0,0 +1 @@ +../../../mlkem/mlkem_native.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/native b/examples/bring_your_own_fips202/mlkem_native/native new file mode 120000 index 000000000..9fa1816ac --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/native @@ -0,0 +1 @@ +../../../mlkem/native \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/ntt.c b/examples/bring_your_own_fips202/mlkem_native/ntt.c new file mode 120000 index 000000000..957883d8b --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/ntt.c @@ -0,0 +1 @@ +../../../mlkem/ntt.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/ntt.h b/examples/bring_your_own_fips202/mlkem_native/ntt.h new file mode 120000 index 000000000..4fa1e50b9 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/ntt.h @@ -0,0 +1 @@ +../../../mlkem/ntt.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/params.h b/examples/bring_your_own_fips202/mlkem_native/params.h new file mode 120000 index 000000000..cb0a9eb7d --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/params.h @@ -0,0 +1 @@ +../../../mlkem/params.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/poly.c b/examples/bring_your_own_fips202/mlkem_native/poly.c new file mode 120000 index 000000000..9fba295ef --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/poly.c @@ -0,0 +1 @@ +../../../mlkem/poly.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/poly.h b/examples/bring_your_own_fips202/mlkem_native/poly.h new file mode 120000 index 000000000..94590db4b --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/poly.h @@ -0,0 +1 @@ +../../../mlkem/poly.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/polyvec.c b/examples/bring_your_own_fips202/mlkem_native/polyvec.c new file mode 120000 index 000000000..83d5cd88f --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/polyvec.c @@ -0,0 +1 @@ +../../../mlkem/polyvec.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/polyvec.h b/examples/bring_your_own_fips202/mlkem_native/polyvec.h new file mode 120000 index 000000000..cc19e1f8c --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/polyvec.h @@ -0,0 +1 @@ +../../../mlkem/polyvec.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/randombytes.h b/examples/bring_your_own_fips202/mlkem_native/randombytes.h new file mode 120000 index 000000000..6222dc6fc --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/randombytes.h @@ -0,0 +1 @@ +../../../mlkem/randombytes.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/reduce.h b/examples/bring_your_own_fips202/mlkem_native/reduce.h new file mode 120000 index 000000000..f543b43a2 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/reduce.h @@ -0,0 +1 @@ +../../../mlkem/reduce.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/rej_uniform.c b/examples/bring_your_own_fips202/mlkem_native/rej_uniform.c new file mode 120000 index 000000000..fb0ee1f67 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/rej_uniform.c @@ -0,0 +1 @@ +../../../mlkem/rej_uniform.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/rej_uniform.h b/examples/bring_your_own_fips202/mlkem_native/rej_uniform.h new file mode 120000 index 000000000..490f38487 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/rej_uniform.h @@ -0,0 +1 @@ +../../../mlkem/rej_uniform.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/symmetric.h b/examples/bring_your_own_fips202/mlkem_native/symmetric.h new file mode 120000 index 000000000..0840846b8 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/symmetric.h @@ -0,0 +1 @@ +../../../mlkem/symmetric.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/sys.h b/examples/bring_your_own_fips202/mlkem_native/sys.h new file mode 120000 index 000000000..75642582b --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/sys.h @@ -0,0 +1 @@ +../../../mlkem/sys.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/verify.c b/examples/bring_your_own_fips202/mlkem_native/verify.c new file mode 120000 index 000000000..99bb83c2c --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/verify.c @@ -0,0 +1 @@ +../../../mlkem/verify.c \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/verify.h b/examples/bring_your_own_fips202/mlkem_native/verify.h new file mode 120000 index 000000000..295ed23cc --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/verify.h @@ -0,0 +1 @@ +../../../mlkem/verify.h \ No newline at end of file diff --git a/examples/bring_your_own_fips202/mlkem_native/zetas.c b/examples/bring_your_own_fips202/mlkem_native/zetas.c new file mode 120000 index 000000000..b2959f3f6 --- /dev/null +++ b/examples/bring_your_own_fips202/mlkem_native/zetas.c @@ -0,0 +1 @@ +../../../mlkem/zetas.c \ No newline at end of file From 5c9400ccb9ca8031e195c30c9aa975688a28cb92 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:30:10 +0000 Subject: [PATCH 02/13] Examples: Fix some signed vs unsigned comparison warnings Signed-off-by: Hanno Becker --- examples/custom_backend/main.c | 2 +- examples/mlkem_native_as_code_package/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/custom_backend/main.c b/examples/custom_backend/main.c index 1ea54442c..386467cc2 100644 --- a/examples/custom_backend/main.c +++ b/examples/custom_backend/main.c @@ -59,7 +59,7 @@ int main(void) printf("Shared secret: "); { - int i; + size_t i; for (i = 0; i < sizeof(key_a); i++) printf("%02x", key_a[i]); } diff --git a/examples/mlkem_native_as_code_package/main.c b/examples/mlkem_native_as_code_package/main.c index 7f3237ca6..3a38d4583 100644 --- a/examples/mlkem_native_as_code_package/main.c +++ b/examples/mlkem_native_as_code_package/main.c @@ -46,7 +46,7 @@ int main(void) printf("Shared secret: "); { - int i; + size_t i; for (i = 0; i < sizeof(key_a); i++) printf("%02x", key_a[i]); } From a3ffe92d2f4643af80c7501756682477e75f4845 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:30:44 +0000 Subject: [PATCH 03/13] Examples: Remove `#warning` message about test RNG We have enough warnings in other places, and those clutter the build and lead to failures with `-Werror`. We also don't have them for the test builds. Signed-off-by: Hanno Becker --- examples/bring_your_own_fips202/test_only_rng/notrandombytes.c | 3 --- examples/custom_backend/test_only_rng/notrandombytes.c | 3 --- .../test_only_rng/notrandombytes.c | 3 --- examples/monolithic_build/test_only_rng/notrandombytes.c | 3 --- 4 files changed, 12 deletions(-) diff --git a/examples/bring_your_own_fips202/test_only_rng/notrandombytes.c b/examples/bring_your_own_fips202/test_only_rng/notrandombytes.c index 93807622d..26393d9a8 100644 --- a/examples/bring_your_own_fips202/test_only_rng/notrandombytes.c +++ b/examples/bring_your_own_fips202/test_only_rng/notrandombytes.c @@ -12,9 +12,6 @@ * */ -#warning !!! WARNING !!! -#warning THIS BUILD IS USING A TEST-ONLY RANDOM NUMBER GENERATOR WHICH MUST NOT BE USED IN PRODUCTION - #include #include "randombytes.h" diff --git a/examples/custom_backend/test_only_rng/notrandombytes.c b/examples/custom_backend/test_only_rng/notrandombytes.c index 93807622d..26393d9a8 100644 --- a/examples/custom_backend/test_only_rng/notrandombytes.c +++ b/examples/custom_backend/test_only_rng/notrandombytes.c @@ -12,9 +12,6 @@ * */ -#warning !!! WARNING !!! -#warning THIS BUILD IS USING A TEST-ONLY RANDOM NUMBER GENERATOR WHICH MUST NOT BE USED IN PRODUCTION - #include #include "randombytes.h" diff --git a/examples/mlkem_native_as_code_package/test_only_rng/notrandombytes.c b/examples/mlkem_native_as_code_package/test_only_rng/notrandombytes.c index 93807622d..26393d9a8 100644 --- a/examples/mlkem_native_as_code_package/test_only_rng/notrandombytes.c +++ b/examples/mlkem_native_as_code_package/test_only_rng/notrandombytes.c @@ -12,9 +12,6 @@ * */ -#warning !!! WARNING !!! -#warning THIS BUILD IS USING A TEST-ONLY RANDOM NUMBER GENERATOR WHICH MUST NOT BE USED IN PRODUCTION - #include #include "randombytes.h" diff --git a/examples/monolithic_build/test_only_rng/notrandombytes.c b/examples/monolithic_build/test_only_rng/notrandombytes.c index 93807622d..26393d9a8 100644 --- a/examples/monolithic_build/test_only_rng/notrandombytes.c +++ b/examples/monolithic_build/test_only_rng/notrandombytes.c @@ -12,9 +12,6 @@ * */ -#warning !!! WARNING !!! -#warning THIS BUILD IS USING A TEST-ONLY RANDOM NUMBER GENERATOR WHICH MUST NOT BE USED IN PRODUCTION - #include #include "randombytes.h" From 59c1696335a1a5c0412c21da4a884daf7b6205e5 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:32:24 +0000 Subject: [PATCH 04/13] Examples: Use pedantic CFLAGS, allow CROSS_PREFIX and EXEC_WRAPPER This paves the way for the integration of the examples into `tests`, which is run with cross builds and custom cflags as well. Signed-off-by: Hanno Becker --- examples/bring_your_own_fips202/Makefile | 27 ++++++++++++++++-- examples/custom_backend/Makefile | 28 +++++++++++++++++-- .../mlkem_native_as_code_package/Makefile | 26 +++++++++++++++-- examples/monolithic_build/Makefile | 17 ++++++++--- 4 files changed, 88 insertions(+), 10 deletions(-) diff --git a/examples/bring_your_own_fips202/Makefile b/examples/bring_your_own_fips202/Makefile index 83d9e0079..86225aa81 100644 --- a/examples/bring_your_own_fips202/Makefile +++ b/examples/bring_your_own_fips202/Makefile @@ -2,6 +2,14 @@ .PHONY: build run clean +# Append cross-prefix for cross compilation +# Remove or ignore for native builds +CC ?= gcc +# When called from the root Makefile, CROSS_PREFIX has already been added here +ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) +CC := $(CROSS_PREFIX)$(CC) +endif + # Part A: # # mlkem-native source and header files @@ -48,19 +56,34 @@ ALL_SOURCE=$(MLKEM_NATIVE_SOURCE) $(FIPS202_SOURCE) $(RNG_SOURCE) $(APP_SOURCE) BUILD_DIR=build BIN=test_binary +CFLAGS := \ + -Wall \ + -Wextra \ + -Wmissing-prototypes \ + -Wshadow \ + -Wpointer-arith \ + -Wno-long-long \ + -Wno-unknown-pragmas \ + -Wno-unused-command-line-argument \ + -fomit-frame-pointer \ + -std=c99 \ + -pedantic \ + -MMD \ + $(CFLAGS) + BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN) $(BINARY_NAME_FULL): $(ALL_SOURCE) echo "$@" mkdir -p $(BUILD_DIR) - $(CC) $(INC) $^ -o $@ + $(CC) $(CFLAGS) $(INC) $^ -o $@ all: run build: $(BINARY_NAME_FULL) run: $(BINARY_NAME_FULL) - ./$(BINARY_NAME_FULL) + $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL) clean: rm -rf $(BUILD_DIR) diff --git a/examples/custom_backend/Makefile b/examples/custom_backend/Makefile index b1dad8549..0f3bc8b3e 100644 --- a/examples/custom_backend/Makefile +++ b/examples/custom_backend/Makefile @@ -2,6 +2,14 @@ .PHONY: build run clean +# Append cross-prefix for cross compilation +# Remove or ignore for native builds +CC ?= gcc +# When called from the root Makefile, CROSS_PREFIX has already been added here +ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) +CC := $(CROSS_PREFIX)$(CC) +endif + # Part A: # # mlkem-native source and header files @@ -44,7 +52,23 @@ ALL_SOURCE=$(MLKEM_NATIVE_SOURCE) $(RNG_SOURCE) $(APP_SOURCE) BUILD_DIR=build BIN=test_binary -CFLAGS=-DMLKEM_NATIVE_CONFIG_FILE="\"custom_config.h\"" +CFLAGS := \ + -Wall \ + -Wextra \ + -Wmissing-prototypes \ + -Wshadow \ + -Werror \ + -Wpointer-arith \ + -Wno-long-long \ + -Wno-unknown-pragmas \ + -Wno-unused-command-line-argument \ + -fomit-frame-pointer \ + -std=c99 \ + -pedantic \ + -MMD \ + $(CFLAGS) + +CFLAGS+=-DMLKEM_NATIVE_CONFIG_FILE="\"custom_config.h\"" BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN) @@ -58,7 +82,7 @@ all: run build: $(BINARY_NAME_FULL) run: $(BINARY_NAME_FULL) - ./$(BINARY_NAME_FULL) + $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL) clean: rm -rf $(BUILD_DIR) diff --git a/examples/mlkem_native_as_code_package/Makefile b/examples/mlkem_native_as_code_package/Makefile index 231999a26..03848ae29 100644 --- a/examples/mlkem_native_as_code_package/Makefile +++ b/examples/mlkem_native_as_code_package/Makefile @@ -2,6 +2,14 @@ .PHONY: build run clean +# Append cross-prefix for cross compilation +# Remove or ignore for native builds +CC ?= gcc +# When called from the root Makefile, CROSS_PREFIX has already been added here +ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) +CC := $(CROSS_PREFIX)$(CC) +endif + # Part A: # # mlkem-native source and header files @@ -44,7 +52,21 @@ ALL_SOURCE=$(MLKEM_NATIVE_SOURCE) $(RNG_SOURCE) $(APP_SOURCE) BUILD_DIR=build BIN=test_binary -CFLAGS=-std=c90 +CFLAGS := \ + -Wall \ + -Wextra \ + -Wmissing-prototypes \ + -Wshadow \ + -Werror \ + -Wpointer-arith \ + -Wno-long-long \ + -Wno-unknown-pragmas \ + -Wno-unused-command-line-argument \ + -fomit-frame-pointer \ + -std=c99 \ + -pedantic \ + -MMD \ + $(CFLAGS) BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN) @@ -58,7 +80,7 @@ all: run build: $(BINARY_NAME_FULL) run: $(BINARY_NAME_FULL) - ./$(BINARY_NAME_FULL) + $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL) clean: rm -rf $(BUILD_DIR) diff --git a/examples/monolithic_build/Makefile b/examples/monolithic_build/Makefile index 2d6d9e242..fd0ccb1dc 100644 --- a/examples/monolithic_build/Makefile +++ b/examples/monolithic_build/Makefile @@ -2,6 +2,14 @@ .PHONY: build run clean +# Append cross-prefix for cross compilation +# Remove or ignore for native builds +CC ?= gcc +# When called from the root Makefile, CROSS_PREFIX has already been added here +ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) +CC := $(CROSS_PREFIX)$(CC) +endif + # Part A: # # mlkem-native source and header files @@ -47,11 +55,12 @@ CFLAGS := \ -Wno-long-long \ -Wno-unknown-pragmas \ -Wno-unused-command-line-argument \ - -O3 \ -fomit-frame-pointer \ - -std=c90 \ + -std=c99 \ -pedantic \ - -MMD + -MMD \ + $(CFLAGS) + # Set this flag to give all non-global functions internal linkage CFLAGS += -DMLKEM_NATIVE_MONOBUILD @@ -67,7 +76,7 @@ all: run build: $(BINARY_NAME_FULL) run: $(BINARY_NAME_FULL) - ./$(BINARY_NAME_FULL) + $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL) clean: rm -rf $(BUILD_DIR) From b586071f37a312214fa867d40581f7d4808befae Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:33:18 +0000 Subject: [PATCH 05/13] Makefile: Add examples into scope of `make clean` Signed-off-by: Hanno Becker --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 0de24810c..c47b9b688 100644 --- a/Makefile +++ b/Makefile @@ -144,3 +144,7 @@ run_bench_components: \ clean: -$(RM) -rf *.gcno *.gcda *.lcov *.o *.so -$(RM) -rf $(BUILD_DIR) + -make clean -C examples/bring_your_own_fips202 >/dev/null + -make clean -C examples/custom_backend >/dev/null + -make clean -C examples/mlkem_native_as_code_package >/dev/null + -make clean -C examples/monolithic_build >/dev/null From da19d9e0cf1d31c6e0a2fe86c0cc98fa939b6049 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:33:33 +0000 Subject: [PATCH 06/13] Tests: Add `tests examples` option Now you can run `tests examples` or `tests examples -l exA -l exB` to run (a list of) examples. It is also integrated into `tests all` by default, which means examples are now run in CI in a multitude of compiler and configuration settings. Signed-off-by: Hanno Becker --- scripts/lib/mlkem_test.py | 60 +++++++++++++++++++++++++----- scripts/lib/util.py | 78 ++++++++++++++++++++++++++++++++++++--- scripts/tests | 37 +++++++++++++++++++ 3 files changed, 160 insertions(+), 15 deletions(-) diff --git a/scripts/lib/mlkem_test.py b/scripts/lib/mlkem_test.py index daaf977b9..65c59ffce 100644 --- a/scripts/lib/mlkem_test.py +++ b/scripts/lib/mlkem_test.py @@ -66,24 +66,44 @@ def compile_mode(self): def _compile_schemes(self, test_type, opt): """compile or cross compile with some extra environment variables and makefile arguments""" - opt_label = "opt" if opt else "no_opt" + if opt is None: + opt_label = "" + elif opt is True: + opt_label = " opt" + else: + opt_label = " no_opt" github_log( - f"::group::compile {self.compile_mode()} {opt_label} {test_type.desc()}" + f"::group::compile {self.compile_mode()}{opt_label} {test_type.desc()}" ) log = logger(test_type, "Compile", self.args.cross_prefix, opt) - extra_make_args = [f"OPT={int(opt)}", f"AUTO={int(self.args.auto)}"] + extra_make_args = [] + # Those options are not used in the examples + if test_type.is_example() is False: + extra_make_args += [f"OPT={int(opt)}", f"AUTO={int(self.args.auto)}"] if test_type.is_benchmark() is True: extra_make_args += [f"CYCLES={self.args.cycles}"] + if test_type.make_dir() != "": + extra_make_args += ["-C", test_type.make_dir()] extra_make_args += self.make_j() - args = ["make", test_type.make_target()] + extra_make_args + target = test_type.make_target() + target = [target] if target != "" else [] + args = ["make"] + target + extra_make_args + + # Force static compilation for cross builds + cflags = self.args.cflags + if cflags is None: + cflags = "" + + if test_type.is_example() and self.args.cross_prefix != "": + cflags += " -static" env_update = {} - if self.args.cflags is not None and self.args.cflags != "": - env_update["CFLAGS"] = self.args.cflags + if cflags != "": + env_update["CFLAGS"] = cflags if self.args.cross_prefix != "": env_update["CROSS_PREFIX"] = self.args.cross_prefix @@ -100,7 +120,7 @@ def _compile_schemes(self, test_type, opt): if p.returncode != 0: log.error(f"make failed: {p.returncode}") - self.fail(f"Compilation for ({test_type},{opt_label})") + self.fail(f"Compilation for ({test_type}{opt_label})") github_log("::endgroup::") @@ -119,7 +139,12 @@ def _run_scheme( - suppress_output: Indicate whether to suppress or print-and-return the output """ - opt_label = "opt" if opt else "no_opt" + if opt is None: + opt_label = "" + elif opt is True: + opt_label = " opt" + else: + opt_label = " no_opt" if scheme is None: scheme_str = "All" @@ -129,8 +154,10 @@ def _run_scheme( log = logger(test_type, scheme_str, self.args.cross_prefix, opt) args = ["make", test_type.make_run_target(scheme)] - if test_type.is_benchmark() is False: + if test_type.is_benchmark() is False and test_type.is_example() is False: args += self.make_j() + if test_type.make_dir() != "": + args += ["-C", test_type.make_dir()] env_update = {} if len(self.cmd_prefix()) > 0: @@ -147,7 +174,7 @@ def _run_scheme( if p.returncode != 0: log.error(f"'{cmd_str}' failed with with {p.returncode}") log.error(p.stderr.decode()) - self.fail(f"{test_type.desc()} ({opt_label}, {scheme_str})") + self.fail(f"{test_type.desc()} ({scheme_str}{opt_label})") return True # Failure elif suppress_output is True: if self.args.verbose is True: @@ -249,6 +276,15 @@ def _acvp(opt): self.check_fail() + def examples(self): + if self.args.l is None: + l = TEST_TYPES.examples() + else: + l = list(map(TEST_TYPES.from_string, self.args.l)) + for e in l: + self._compile_schemes(e, None) + self._run_scheme(e, None, None) + def bench(self): output = self.args.output components = self.args.components @@ -312,6 +348,7 @@ def all(self): kat = self.args.kat nistkat = self.args.nistkat acvp = self.args.acvp + examples = self.args.examples def _all(opt): if func is True: @@ -340,6 +377,9 @@ def _all(opt): if self.do_opt(): _all(True) + if examples is True: + self.examples() + self.check_fail() def cbmc(self): diff --git a/scripts/lib/util.py b/scripts/lib/util.py index a4a2622fe..89f98ccdb 100644 --- a/scripts/lib/util.py +++ b/scripts/lib/util.py @@ -37,10 +37,35 @@ class TEST_TYPES(Enum): KAT = 4 BENCH_COMPONENTS = 5 ACVP = 6 + BRING_YOUR_OWN_FIPS202 = 7 + CUSTOM_BACKEND = 8 + MLKEM_NATIVE_AS_CODE_PACKAGE = 9 + MONOLITHIC_BUILD = 10 def is_benchmark(self): return self in [TEST_TYPES.BENCH, TEST_TYPES.BENCH_COMPONENTS] + def is_example(self): + return self in TEST_TYPES.examples() + + @staticmethod + def examples(): + return [ + TEST_TYPES.BRING_YOUR_OWN_FIPS202, + TEST_TYPES.CUSTOM_BACKEND, + TEST_TYPES.MLKEM_NATIVE_AS_CODE_PACKAGE, + TEST_TYPES.MONOLITHIC_BUILD, + ] + + @staticmethod + def from_string(s): + for e in TEST_TYPES.examples(): + if str.lower(e.name) == str.lower(s): + return e + raise Exception( + f"Could not find example {s}. Examples: {list(map(lambda e: str.lower(e.name), TEST_TYPES.examples()))}" + ) + def desc(self): if self == TEST_TYPES.FUNC: return "Functional Test" @@ -54,6 +79,25 @@ def desc(self): return "Kat Test" if self == TEST_TYPES.ACVP: return "ACVP Test" + if self == TEST_TYPES.BRING_YOUR_OWN_FIPS202: + return "Example (Bring-Your-Own-FIPS202)" + if self == TEST_TYPES.CUSTOM_BACKEND: + return "Example (Custom Backend)" + if self == TEST_TYPES.MLKEM_NATIVE_AS_CODE_PACKAGE: + return "Example (mlkem-native as code package)" + if self == TEST_TYPES.MONOLITHIC_BUILD: + return "Example (monolithic build)" + + def make_dir(self): + if self == TEST_TYPES.BRING_YOUR_OWN_FIPS202: + return "examples/bring_your_own_fips202" + if self == TEST_TYPES.CUSTOM_BACKEND: + return "examples/custom_backend" + if self == TEST_TYPES.MLKEM_NATIVE_AS_CODE_PACKAGE: + return "examples/mlkem_native_as_code_package" + if self == TEST_TYPES.MONOLITHIC_BUILD: + return "examples/monolithic_build" + return "" def make_target(self): if self == TEST_TYPES.FUNC: @@ -68,12 +112,25 @@ def make_target(self): return "kat" if self == TEST_TYPES.ACVP: return "acvp" + if self == TEST_TYPES.BRING_YOUR_OWN_FIPS202: + return "" + if self == TEST_TYPES.CUSTOM_BACKEND: + return "" + if self == TEST_TYPES.MLKEM_NATIVE_AS_CODE_PACKAGE: + return "" + if self == TEST_TYPES.MONOLITHIC_BUILD: + return "" def make_run_target(self, scheme): + t = self.make_target() + if t == "": + run_t = "run" + else: + run_t = f"run_{t}" if scheme is not None: - return f"run_{self.make_target()}_{scheme.suffix()}" + return f"{run_t}_{scheme.suffix()}" else: - return f"run_{self.make_target()}" + return run_t def dict2str(dict): @@ -179,12 +236,23 @@ def config_logger(verbose): def logger(test_type, scheme, cross_prefix, opt): """Emit line indicating the processing of the given test""" compile_mode = "cross" if cross_prefix else "native" - implementation = "opt" if opt else "no_opt" + if opt is None: + opt_label = "" + elif opt is True: + opt_label = " opt" + else: + opt_label = " no_opt" + + if test_type.is_example(): + sz = 40 + else: + sz = 18 return logging.getLogger( - "{:<18} {:<11} {:<17}".format( + "{0:<{1}} {2:<11} {3:<17}".format( (test_type.desc()), + sz, str(scheme), - "({}, {}):".format(compile_mode, implementation), + "({}{}):".format(compile_mode, opt_label), ) ) diff --git a/scripts/tests b/scripts/tests index b2e87ecaf..0a3bd8870 100755 --- a/scripts/tests +++ b/scripts/tests @@ -120,11 +120,43 @@ def cli(): "--no-acvp", action="store_false", dest="acvp", help="Do not run acvp test" ) + examples_group = all_parser.add_mutually_exclusive_group() + examples_group.add_argument( + "--examples", + action="store_true", + dest="examples", + help="Run examples", + default=True, + ) + examples_group.add_argument( + "--no-examples", + action="store_false", + dest="examples", + help="Do not run examples", + ) + # acvp arguments acvp_parser = cmd_subparsers.add_parser( "acvp", help="Run ACVP client", parents=[common_parser] ) + # examples arguments + examples_parser = cmd_subparsers.add_parser( + "examples", help="Run examples", parents=[common_parser] + ) + + examples_parser.add_argument( + "-l", + help="Explicitly list the examples to run; can be called multiple times", + choices=[ + "bring_your_own_fips202", + "custom_backend", + "mlkem_native_as_code_package", + "monolithic_build", + ], + action="append", + ) + # bench arguments bench_parser = cmd_subparsers.add_parser( "bench", @@ -193,11 +225,16 @@ def cli(): ) args = main_parser.parse_args() + if not hasattr(args, "mac_taskpolicy"): args.mac_taskpolicy = None + if not hasattr(args, "l"): + args.l = None if args.cmd == "all": Tests(args).all() + elif args.cmd == "examples": + Tests(args).examples() elif args.cmd == "acvp": Tests(args).acvp() elif args.cmd == "bench": From a7be0e13007f626ff43fa653f6e5ddd8f97aeb14 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:27:58 +0000 Subject: [PATCH 07/13] Debug: Add namespacing Signed-off-by: Hanno Becker --- .../monolithic_build/mlkem_native_monobuild.c | 15 +++++++++++++++ mlkem/debug/debug.h | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/monolithic_build/mlkem_native_monobuild.c b/examples/monolithic_build/mlkem_native_monobuild.c index 8573d1d38..e7c767fb0 100644 --- a/examples/monolithic_build/mlkem_native_monobuild.c +++ b/examples/monolithic_build/mlkem_native_monobuild.c @@ -359,6 +359,21 @@ #undef MLKEM_DEBUG_H #endif +/* mlkem/debug/debug.h */ +#if defined(mlkem_debug_assert) +#undef mlkem_debug_assert +#endif + +/* mlkem/debug/debug.h */ +#if defined(mlkem_debug_check_bounds) +#undef mlkem_debug_check_bounds +#endif + +/* mlkem/debug/debug.h */ +#if defined(mlkem_debug_print_error) +#undef mlkem_debug_print_error +#endif + /* mlkem/debug/debug.h */ #if defined(CASSERT) #undef CASSERT diff --git a/mlkem/debug/debug.h b/mlkem/debug/debug.h index 5838ae4bf..5f7d02ba6 100644 --- a/mlkem/debug/debug.h +++ b/mlkem/debug/debug.h @@ -25,6 +25,7 @@ * - description: Textual description of assertion * - val: Value asserted to be non-zero **************************************************/ +#define mlkem_debug_assert MLKEM_NAMESPACE(mlkem_debug_assert) void mlkem_debug_assert(const char *file, int line, const char *description, const int val); @@ -45,12 +46,14 @@ void mlkem_debug_assert(const char *file, int line, const char *description, * - lower_bound_exclusive: Exclusive lower bound * - upper_bound_exclusive: Exclusive upper bound **************************************************/ +#define mlkem_debug_check_bounds MLKEM_NAMESPACE(mlkem_debug_check_bounds) void mlkem_debug_check_bounds(const char *file, int line, const char *description, const int16_t *ptr, unsigned len, int lower_bound_exclusive, int upper_bound_exclusive); /* Print error message to stderr alongside file and line information */ +#define mlkem_debug_print_error MLKEM_NAMESPACE(mlkem_debug_print_error) void mlkem_debug_print_error(const char *file, int line, const char *msg); /* Check assertion, calling exit() upon failure @@ -163,7 +166,8 @@ void mlkem_debug_print_error(const char *file, int line, const char *msg); typedef struct \ { \ unsigned int MLKEM_CONCAT(static_assertion_, msg) : (cond) ? 1 : -1; \ - } MLKEM_CONCAT(static_assertion_, msg) __attribute__((unused)); + } MLKEM_CONCAT(MLKEM_NAMESPACE(static_assertion_), msg) \ + __attribute__((unused)); #define MLKEM_STATIC_ASSERT_ADD_LINE0(cond, suffix) \ MLKEM_STATIC_ASSERT_DEFINE(cond, MLKEM_CONCAT(at_line_, suffix)) From 550e620487f67db7901c504213a1c82f6a0bff5a Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:47:51 +0000 Subject: [PATCH 08/13] Examples: Expand documentation of monobuild example Signed-off-by: Hanno Becker --- examples/monolithic_build/Makefile | 10 +-- examples/monolithic_build/README.md | 74 +++++++++++++++++--- examples/monolithic_build/mlkem_native_all.c | 2 +- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/examples/monolithic_build/Makefile b/examples/monolithic_build/Makefile index fd0ccb1dc..5f8956bdd 100644 --- a/examples/monolithic_build/Makefile +++ b/examples/monolithic_build/Makefile @@ -14,8 +14,10 @@ endif # # 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. +# Here, we use just a single monolithic compilation unit to include +# multiple instances of mlkem-native. + +MLKEM_NATIVE_SOURCE=mlkem_native_all.c INC= INC+=-I./ @@ -39,9 +41,9 @@ RNG_SOURCE=$(wildcard test_only_rng/*.c) # Part C: # # Your application source code -APP_SOURCE=main.c mlkem_native_all.c +APP_SOURCE=main.c -ALL_SOURCE=$(MLKEM_NATIVE_SOURCE) $(RNG_SOURCE) $(APP_SOURCE) +ALL_SOURCE=$(RNG_SOURCE) $(APP_SOURCE) $(MLKEM_NATIVE_SOURCE) BUILD_DIR=build BIN=test_binary diff --git a/examples/monolithic_build/README.md b/examples/monolithic_build/README.md index 5fed6c554..d1a9c8914 100644 --- a/examples/monolithic_build/README.md +++ b/examples/monolithic_build/README.md @@ -1,20 +1,76 @@ [//]: # (SPDX-License-Identifier: CC-BY-4.0) -# Using mlkem-native as a code package +# Multi-level mlkem-native in a single compilation unit -This directory contains a minimal example for how to use mlkem-native as a code package, without modifications. +This directory contains a minimal example for how to build multiple instances of mlkem-native in a single compilation +unit. -## Components +The auto-generated source file [mlkem_native_monobuild.c](mlkem_native_monobuild.c) includes all mlkem-native C source +files. Moreover, it clears all `#define`s clauses set by mlkem-native at the end, and is hence amenable to multiple +inclusion in another compilation unit. -An application using mlkem-native as-is needs to include the following components: +The manually written source file [mlkem_native_all.c](mlkem_native_all.c) includes +[mlkem_native_monobuild.c](mlkem_native_monobuild.c) three times, once for each of the three configuration files +[config_512.h](config_512.h), [config_768.h](config_768.h), +[config_1024.h](config_1024.h) for the different levels. For each inclusion, it sets `MLKEM_NATIVE_CONFIG_FILE` +appropriately first, and then includes the monobuild: +```C +/* Three instances of mlkem-native for all security levels */ -1. mlkem-native source tree, including [`mlkem/`](../../mlkem) and [`mlkem/fips202/`](../../mlkem/fips202). -2. A secure pseudo random number generator, implementing [`randombytes.h`](../../mlkem/randombytes.h). -3. The application source code +#define MLKEM_NATIVE_CONFIG_FILE "config_512.h" +#include "mlkem_native_monobuild.c" +#undef MLKEM_NATIVE_CONFIG_FILE -**WARNING:** The `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation -outside of testing. +#define MLKEM_NATIVE_CONFIG_FILE "config_768.h" +#include "mlkem_native_monobuild.c" +#undef MLKEM_NATIVE_CONFIG_FILE + +#define MLKEM_NATIVE_CONFIG_FILE "config_1024.h" +#include "mlkem_native_monobuild.c" +#undef MLKEM_NATIVE_CONFIG_FILE +``` + +To make the monolithic multi-level build accessible from the application sources, we provide +[mlkem_native_all.h](mlkem_native_all.h), which includes [mlkem_native.h](../../mlkem/mlkem_native.h) once per +configuration. Note that we don't refer to the configuration using `MLKEM_NATIVE_CONFIG_FILE`, but by setting +`BUILD_INFO_XXX` explicitly. Otherwise, [mlkem_native.h](../../mlkem/mlkem_native.h) would include the confg, which +would lead to name-clashes upon multiple use. + +```C +/* API for MLKEM-512 */ +#define BUILD_INFO_LVL 512 +#define BUILD_INFO_NAMESPACE(sym) mlkem512_##sym +#define BUILD_INFO_NO_STANDARD_API +#include "mlkem_native.h" +#undef BUILD_INFO_LVL +#undef BUILD_INFO_NAMESPACE +#undef BUILD_INFO_NO_STANDARD_API +#undef MLKEM_NATIVE_H + +/* API for MLKEM-768 */ +#define BUILD_INFO_LVL 768 +#define BUILD_INFO_NAMESPACE(sym) mlkem768_##sym +#define BUILD_INFO_NO_STANDARD_API +#include "mlkem_native.h" +#undef BUILD_INFO_LVL +#undef BUILD_INFO_NAMESPACE +#undef BUILD_INFO_NO_STANDARD_API +#undef MLKEM_NATIVE_H + +/* API for MLKEM-1024 */ +#define BUILD_INFO_LVL 1024 +#define BUILD_INFO_NAMESPACE(sym) mlkem1024_##sym +#define BUILD_INFO_NO_STANDARD_API +#include "mlkem_native.h" +#undef BUILD_INFO_LVL +#undef BUILD_INFO_NAMESPACE +#undef BUILD_INFO_NO_STANDARD_API +#undef MLKEM_NATIVE_H +``` ## Usage Build this example with `make build`, run with `make run`. + +**WARNING:** The `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation +outside of testing. diff --git a/examples/monolithic_build/mlkem_native_all.c b/examples/monolithic_build/mlkem_native_all.c index 3e19f0e3d..d1a522674 100644 --- a/examples/monolithic_build/mlkem_native_all.c +++ b/examples/monolithic_build/mlkem_native_all.c @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* Two instances of mlkem-native for two security levels */ +/* Three instances of mlkem-native for all security levels */ #define MLKEM_NATIVE_CONFIG_FILE "config_512.h" #include "mlkem_native_monobuild.c" From 42a5b961354290e37fa215855977de12bdb8c964 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 04:57:11 +0000 Subject: [PATCH 09/13] Examples: Make tinySHA3 example C90 compliant Signed-off-by: Hanno Becker --- .../custom_fips202/tiny_sha3/sha3.c | 42 +++++++++---------- .../custom_fips202/tiny_sha3/sha3.h | 30 ++++++------- .../fips202/native/custom/src/sha3.c | 42 +++++++++---------- .../fips202/native/custom/src/sha3.h | 30 ++++++------- 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.c b/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.c index c21684ae5..27213b43a 100644 --- a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.c +++ b/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.c @@ -1,18 +1,18 @@ -// SPDX-License-Identifier: MIT -// -// sha3.c -// 19-Nov-11 Markku-Juhani O. Saarinen +/* 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 +/* 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 +/* update the state with given number of rounds */ void sha3_keccakf(uint64_t st[25]) { - // constants + /* constants */ const uint64_t keccakf_rndc[24] = { 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, @@ -27,14 +27,14 @@ void sha3_keccakf(uint64_t st[25]) 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 + /* 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 + /* endianess conversion. this is redundant on little-endian targets */ for (i = 0; i < 25; i++) { v = (uint8_t *)&st[i]; @@ -45,10 +45,10 @@ void sha3_keccakf(uint64_t st[25]) } #endif - // actual iteration + /* actual iteration */ for (r = 0; r < KECCAKF_ROUNDS; r++) { - // Theta + /* Theta */ for (i = 0; i < 5; i++) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; @@ -59,7 +59,7 @@ void sha3_keccakf(uint64_t st[25]) st[j + i] ^= t; } - // Rho Pi + /* Rho Pi */ t = st[1]; for (i = 0; i < 24; i++) { @@ -69,7 +69,7 @@ void sha3_keccakf(uint64_t st[25]) t = bc[0]; } - // Chi + /* Chi */ for (j = 0; j < 25; j += 5) { for (i = 0; i < 5; i++) @@ -78,12 +78,12 @@ void sha3_keccakf(uint64_t st[25]) st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; } - // Iota + /* Iota */ st[0] ^= keccakf_rndc[r]; } #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - // endianess conversion. this is redundant on little-endian targets + /* endianess conversion. this is redundant on little-endian targets */ for (i = 0; i < 25; i++) { v = (uint8_t *)&st[i]; @@ -100,7 +100,7 @@ void sha3_keccakf(uint64_t st[25]) #endif } -// Initialize the context for SHA3 +/* Initialize the context for SHA3 */ int sha3_init(sha3_ctx_t *c, int mdlen) { @@ -115,7 +115,7 @@ int sha3_init(sha3_ctx_t *c, int mdlen) return 1; } -// update state with more data +/* update state with more data */ int sha3_update(sha3_ctx_t *c, const void *data, size_t len) { @@ -137,7 +137,7 @@ int sha3_update(sha3_ctx_t *c, const void *data, size_t len) return 1; } -// finalize and output a hash +/* finalize and output a hash */ int sha3_final(void *md, sha3_ctx_t *c) { @@ -155,7 +155,7 @@ int sha3_final(void *md, sha3_ctx_t *c) return 1; } -// compute a SHA-3 hash (md) of given byte length from "in" +/* compute a SHA-3 hash (md) of given byte length from "in" */ void *sha3(const void *in, size_t inlen, void *md, int mdlen) { @@ -168,7 +168,7 @@ void *sha3(const void *in, size_t inlen, void *md, int mdlen) return md; } -// SHAKE128 and SHAKE256 extensible-output functionality +/* SHAKE128 and SHAKE256 extensible-output functionality */ void shake_xof(sha3_ctx_t *c) { diff --git a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.h b/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.h index fb5276059..8161b7413 100644 --- a/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.h +++ b/examples/bring_your_own_fips202/custom_fips202/tiny_sha3/sha3.h @@ -1,7 +1,7 @@ -// SPDX-License-Identifier: MIT -// -// sha3.h -// 19-Nov-11 Markku-Juhani O. Saarinen +/* SPDX-License-Identifier: MIT + * + * sha3.h + * 19-Nov-11 Markku-Juhani O. Saarinen */ #ifndef SHA3_H #define SHA3_H @@ -17,29 +17,29 @@ #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) #endif -// state context +/* state context */ typedef struct { union - { // state: - uint8_t b[200]; // 8-bit bytes - uint64_t q[25]; // 64-bit words + { /* state: */ + uint8_t b[200]; /* 8-bit bytes */ + uint64_t q[25]; /* 64-bit words */ } st; - int pt, rsiz, mdlen; // these don't overflow + int pt, rsiz, mdlen; /* these don't overflow */ } sha3_ctx_t; -// Compression function. +/* 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 +/* 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 +int sha3_final(void *md, sha3_ctx_t *c); /* digest goes to md */ -// compute a sha3 hash (md) of given byte length from "in" +/* 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 +/* 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 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 index c21684ae5..27213b43a 100644 --- a/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c @@ -1,18 +1,18 @@ -// SPDX-License-Identifier: MIT -// -// sha3.c -// 19-Nov-11 Markku-Juhani O. Saarinen +/* 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 +/* 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 +/* update the state with given number of rounds */ void sha3_keccakf(uint64_t st[25]) { - // constants + /* constants */ const uint64_t keccakf_rndc[24] = { 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, @@ -27,14 +27,14 @@ void sha3_keccakf(uint64_t st[25]) 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 + /* 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 + /* endianess conversion. this is redundant on little-endian targets */ for (i = 0; i < 25; i++) { v = (uint8_t *)&st[i]; @@ -45,10 +45,10 @@ void sha3_keccakf(uint64_t st[25]) } #endif - // actual iteration + /* actual iteration */ for (r = 0; r < KECCAKF_ROUNDS; r++) { - // Theta + /* Theta */ for (i = 0; i < 5; i++) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; @@ -59,7 +59,7 @@ void sha3_keccakf(uint64_t st[25]) st[j + i] ^= t; } - // Rho Pi + /* Rho Pi */ t = st[1]; for (i = 0; i < 24; i++) { @@ -69,7 +69,7 @@ void sha3_keccakf(uint64_t st[25]) t = bc[0]; } - // Chi + /* Chi */ for (j = 0; j < 25; j += 5) { for (i = 0; i < 5; i++) @@ -78,12 +78,12 @@ void sha3_keccakf(uint64_t st[25]) st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; } - // Iota + /* Iota */ st[0] ^= keccakf_rndc[r]; } #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - // endianess conversion. this is redundant on little-endian targets + /* endianess conversion. this is redundant on little-endian targets */ for (i = 0; i < 25; i++) { v = (uint8_t *)&st[i]; @@ -100,7 +100,7 @@ void sha3_keccakf(uint64_t st[25]) #endif } -// Initialize the context for SHA3 +/* Initialize the context for SHA3 */ int sha3_init(sha3_ctx_t *c, int mdlen) { @@ -115,7 +115,7 @@ int sha3_init(sha3_ctx_t *c, int mdlen) return 1; } -// update state with more data +/* update state with more data */ int sha3_update(sha3_ctx_t *c, const void *data, size_t len) { @@ -137,7 +137,7 @@ int sha3_update(sha3_ctx_t *c, const void *data, size_t len) return 1; } -// finalize and output a hash +/* finalize and output a hash */ int sha3_final(void *md, sha3_ctx_t *c) { @@ -155,7 +155,7 @@ int sha3_final(void *md, sha3_ctx_t *c) return 1; } -// compute a SHA-3 hash (md) of given byte length from "in" +/* compute a SHA-3 hash (md) of given byte length from "in" */ void *sha3(const void *in, size_t inlen, void *md, int mdlen) { @@ -168,7 +168,7 @@ void *sha3(const void *in, size_t inlen, void *md, int mdlen) return md; } -// SHAKE128 and SHAKE256 extensible-output functionality +/* SHAKE128 and SHAKE256 extensible-output functionality */ void shake_xof(sha3_ctx_t *c) { 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 index fb5276059..8161b7413 100644 --- a/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.h +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.h @@ -1,7 +1,7 @@ -// SPDX-License-Identifier: MIT -// -// sha3.h -// 19-Nov-11 Markku-Juhani O. Saarinen +/* SPDX-License-Identifier: MIT + * + * sha3.h + * 19-Nov-11 Markku-Juhani O. Saarinen */ #ifndef SHA3_H #define SHA3_H @@ -17,29 +17,29 @@ #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) #endif -// state context +/* state context */ typedef struct { union - { // state: - uint8_t b[200]; // 8-bit bytes - uint64_t q[25]; // 64-bit words + { /* state: */ + uint8_t b[200]; /* 8-bit bytes */ + uint64_t q[25]; /* 64-bit words */ } st; - int pt, rsiz, mdlen; // these don't overflow + int pt, rsiz, mdlen; /* these don't overflow */ } sha3_ctx_t; -// Compression function. +/* 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 +/* 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 +int sha3_final(void *md, sha3_ctx_t *c); /* digest goes to md */ -// compute a sha3 hash (md) of given byte length from "in" +/* 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 +/* 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 From c0fe62cce5764ea63fa58fa5ae25e322fd7572c3 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 05:05:01 +0000 Subject: [PATCH 10/13] Drop unused `poly_xxx` code This was flagged by the monobuild, which marks this function as static and realizes that it's never used. Signed-off-by: Hanno Becker --- cbmc/poly_cbd_eta2/Makefile | 8 ++++++++ cbmc/poly_cbd_eta2/poly_cbd_eta2_harness.c | 3 +++ cbmc/poly_getnoise_eta1122_4x/Makefile | 9 ++++----- .../poly_getnoise_eta1122_4x_harness.c | 3 +++ cbmc/poly_getnoise_eta2/Makefile | 10 ++++++++++ cbmc/poly_getnoise_eta2/poly_getnoise_eta2_harness.c | 3 +++ mlkem/cbd.c | 2 ++ mlkem/cbd.h | 2 ++ mlkem/poly.c | 9 ++++----- mlkem/poly.h | 4 ++++ test/bench_components_mlkem.c | 4 ++++ 11 files changed, 47 insertions(+), 10 deletions(-) diff --git a/cbmc/poly_cbd_eta2/Makefile b/cbmc/poly_cbd_eta2/Makefile index c481cba72..95ee738b4 100644 --- a/cbmc/poly_cbd_eta2/Makefile +++ b/cbmc/poly_cbd_eta2/Makefile @@ -18,7 +18,15 @@ UNWINDSET += PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c PROJECT_SOURCES += $(SRCDIR)/mlkem/cbd.c +# Only relevant for K=2 or K=4 +ifeq ($(MLKEM_K),2) CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_cbd_eta2 +else ifeq ($(MLKEM_K),4) +CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_cbd_eta2 +else +CHECK_FUNCTION_CONTRACTS= +endif + USE_FUNCTION_CONTRACTS= APPLY_LOOP_CONTRACTS=on USE_DYNAMIC_FRAMES=1 diff --git a/cbmc/poly_cbd_eta2/poly_cbd_eta2_harness.c b/cbmc/poly_cbd_eta2/poly_cbd_eta2_harness.c index 1cfb13f9b..f3b27572a 100644 --- a/cbmc/poly_cbd_eta2/poly_cbd_eta2_harness.c +++ b/cbmc/poly_cbd_eta2/poly_cbd_eta2_harness.c @@ -6,8 +6,11 @@ void harness(void) { + /* poly_cbd_eta2() is only defined for MLKEM_K == 2 or 4 */ +#if MLKEM_K == 2 || MLKEM_K == 4 uint8_t *buf; poly *a; poly_cbd_eta2(a, buf); +#endif /* MLKEM_K == 2 || MLKEM_K == 4 */ } diff --git a/cbmc/poly_getnoise_eta1122_4x/Makefile b/cbmc/poly_getnoise_eta1122_4x/Makefile index 45fad13ed..d1f214d46 100644 --- a/cbmc/poly_getnoise_eta1122_4x/Makefile +++ b/cbmc/poly_getnoise_eta1122_4x/Makefile @@ -18,14 +18,13 @@ UNWINDSET += PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c PROJECT_SOURCES += $(SRCDIR)/mlkem/poly.c -CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_getnoise_eta1122_4x -# Depending on MLKEM_K, the code uses shake256 or shake256x4. -# Unfortunately, CBMC complains about unused function contracts, -# so we have to distinguish along MLKEM_K here. +# Only relevant for K=2 ifeq ($(MLKEM_K),2) +CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_getnoise_eta1122_4x USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_cbd_eta1 $(MLKEM_NAMESPACE)poly_cbd_eta2 $(FIPS202_NAMESPACE)shake256 else -USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_cbd_eta1 $(MLKEM_NAMESPACE)poly_cbd_eta2 $(FIPS202_NAMESPACE)shake256x4 +CHECK_FUNCTION_CONTRACTS= +USE_FUNCTION_CONTRACTS= endif APPLY_LOOP_CONTRACTS=on USE_DYNAMIC_FRAMES=1 diff --git a/cbmc/poly_getnoise_eta1122_4x/poly_getnoise_eta1122_4x_harness.c b/cbmc/poly_getnoise_eta1122_4x/poly_getnoise_eta1122_4x_harness.c index 4cad93391..56b1ed2fb 100644 --- a/cbmc/poly_getnoise_eta1122_4x/poly_getnoise_eta1122_4x_harness.c +++ b/cbmc/poly_getnoise_eta1122_4x/poly_getnoise_eta1122_4x_harness.c @@ -6,10 +6,13 @@ void harness(void) { + /* poly_getnoise_eta1122_4x is only defines for MLKEM_K == 2 */ +#if MLKEM_K == 2 uint8_t *seed; poly *r0, *r1, *r2, *r3; uint8_t nonce0, nonce1, nonce2, nonce3; poly_getnoise_eta1122_4x(r0, r1, r2, r3, seed, nonce0, nonce1, nonce2, nonce3); +#endif /* MLKEM_K == 2 */ } diff --git a/cbmc/poly_getnoise_eta2/Makefile b/cbmc/poly_getnoise_eta2/Makefile index 7f51d52ea..6f1f5aa7f 100644 --- a/cbmc/poly_getnoise_eta2/Makefile +++ b/cbmc/poly_getnoise_eta2/Makefile @@ -18,8 +18,18 @@ UNWINDSET += PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c PROJECT_SOURCES += $(SRCDIR)/mlkem/poly.c +# Only relevant for K=2 or K=4 +ifeq ($(MLKEM_K),2) CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_getnoise_eta2 USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_cbd_eta2 $(FIPS202_NAMESPACE)shake256 +else ifeq ($(MLKEM_K),4) +CHECK_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_getnoise_eta2 +USE_FUNCTION_CONTRACTS=$(MLKEM_NAMESPACE)poly_cbd_eta2 $(FIPS202_NAMESPACE)shake256 +else +CHECK_FUNCTION_CONTRACTS= +USE_FUNCTION_CONTRACTS= +endif + APPLY_LOOP_CONTRACTS=on USE_DYNAMIC_FRAMES=1 diff --git a/cbmc/poly_getnoise_eta2/poly_getnoise_eta2_harness.c b/cbmc/poly_getnoise_eta2/poly_getnoise_eta2_harness.c index 46e6c3725..2fcb3b634 100644 --- a/cbmc/poly_getnoise_eta2/poly_getnoise_eta2_harness.c +++ b/cbmc/poly_getnoise_eta2/poly_getnoise_eta2_harness.c @@ -6,9 +6,12 @@ void harness(void) { + /* poly_getnoise_eta2() is only defined for MLKEM_K == 2, 4 */ +#if MLKEM_K == 2 || MLKEM_K == 4 uint8_t *seed; poly *r; uint8_t nonce; poly_getnoise_eta2(r, seed, nonce); +#endif /* MLKEM_K == 2 || MLKEM_K == 4 */ } diff --git a/mlkem/cbd.c b/mlkem/cbd.c index 379f8983d..3eaf55176 100644 --- a/mlkem/cbd.c +++ b/mlkem/cbd.c @@ -143,6 +143,7 @@ void poly_cbd_eta1(poly *r, const uint8_t buf[MLKEM_ETA1 * MLKEM_N / 4]) #endif } +#if MLKEM_K == 2 || MLKEM_K == 4 MLKEM_NATIVE_INTERNAL_API void poly_cbd_eta2(poly *r, const uint8_t buf[MLKEM_ETA2 * MLKEM_N / 4]) { @@ -152,3 +153,4 @@ void poly_cbd_eta2(poly *r, const uint8_t buf[MLKEM_ETA2 * MLKEM_N / 4]) #error "This implementation requires eta2 = 2" #endif } +#endif /* MLKEM_K == 2 || MLKEM_K == 4 */ diff --git a/mlkem/cbd.h b/mlkem/cbd.h index f248dcc4b..ead92d46a 100644 --- a/mlkem/cbd.h +++ b/mlkem/cbd.h @@ -29,6 +29,7 @@ __contract__( ensures(array_abs_bound(r->coeffs, 0, MLKEM_N - 1, MLKEM_ETA1)) ); +#if MLKEM_K == 2 || MLKEM_K == 4 #define poly_cbd_eta2 MLKEM_NAMESPACE(poly_cbd_eta2) /************************************************* * Name: poly_cbd_eta1 @@ -48,5 +49,6 @@ __contract__( assigns(memory_slice(r, sizeof(poly))) ensures(array_abs_bound(r->coeffs, 0, MLKEM_N - 1, MLKEM_ETA2)) ); +#endif /* MLKEM_K == 2 || MLKEM_K == 4 */ #endif diff --git a/mlkem/poly.c b/mlkem/poly.c index e29dbb315..5ee7f8d60 100644 --- a/mlkem/poly.c +++ b/mlkem/poly.c @@ -399,6 +399,7 @@ void poly_getnoise_eta1_4x(poly *r0, poly *r1, poly *r2, poly *r3, POLY_BOUND_MSG(r3, MLKEM_ETA1 + 1, "poly_getnoise_eta1_4x output 3"); } +#if MLKEM_K == 2 || MLKEM_K == 4 MLKEM_NATIVE_INTERNAL_API void poly_getnoise_eta2(poly *r, const uint8_t seed[MLKEM_SYMBYTES], uint8_t nonce) @@ -414,7 +415,9 @@ void poly_getnoise_eta2(poly *r, const uint8_t seed[MLKEM_SYMBYTES], POLY_BOUND_MSG(r, MLKEM_ETA1 + 1, "poly_getnoise_eta2 output"); } +#endif /* MLKEM_K == 2 || MLKEM_K == 4 */ +#if MLKEM_K == 2 MLKEM_NATIVE_INTERNAL_API void poly_getnoise_eta1122_4x(poly *r0, poly *r1, poly *r2, poly *r3, const uint8_t seed[MLKEM_SYMBYTES], @@ -433,15 +436,10 @@ void poly_getnoise_eta1122_4x(poly *r0, poly *r1, poly *r2, poly *r3, extkey[2][MLKEM_SYMBYTES] = nonce2; extkey[3][MLKEM_SYMBYTES] = nonce3; -#if MLKEM_ETA1 == MLKEM_ETA2 - prf_eta1_x4(buf1[0], buf1[1], buf2[0], buf2[1], extkey[0], extkey[1], - extkey[2], extkey[3]); -#else prf_eta1(buf1[0], extkey[0]); prf_eta1(buf1[1], extkey[1]); prf_eta2(buf2[0], extkey[2]); prf_eta2(buf2[1], extkey[3]); -#endif poly_cbd_eta1(r0, buf1[0]); poly_cbd_eta1(r1, buf1[1]); @@ -453,6 +451,7 @@ void poly_getnoise_eta1122_4x(poly *r0, poly *r1, poly *r2, poly *r3, POLY_BOUND_MSG(r2, MLKEM_ETA2 + 1, "poly_getnoise_eta1122_4x output 2"); POLY_BOUND_MSG(r3, MLKEM_ETA2 + 1, "poly_getnoise_eta1122_4x output 3"); } +#endif /* MLKEM_K == 2 */ MLKEM_NATIVE_INTERNAL_API void poly_basemul_montgomery_cached(poly *r, const poly *a, const poly *b, diff --git a/mlkem/poly.h b/mlkem/poly.h index 5dd04e0d3..f14f225fa 100644 --- a/mlkem/poly.h +++ b/mlkem/poly.h @@ -581,6 +581,7 @@ __contract__( #define poly_getnoise_eta2_4x poly_getnoise_eta1_4x #endif /* MLKEM_ETA1 == MLKEM_ETA2 */ +#if MLKEM_K == 2 || MLKEM_K == 4 #define poly_getnoise_eta2 MLKEM_NAMESPACE(poly_getnoise_eta2) /************************************************* * Name: poly_getnoise_eta2 @@ -603,7 +604,9 @@ __contract__( assigns(object_whole(r)) ensures(array_abs_bound(r->coeffs, 0, MLKEM_N - 1, MLKEM_ETA2)) ); +#endif /* MLKEM_K == 2 || MLKEM_K == 4 */ +#if MLKEM_K == 2 #define poly_getnoise_eta1122_4x MLKEM_NAMESPACE(poly_getnoise_eta1122_4x) /************************************************* * Name: poly_getnoise_eta1122_4x @@ -633,6 +636,7 @@ __contract__( && array_abs_bound(r2->coeffs,0, MLKEM_N - 1, MLKEM_ETA2) && array_abs_bound(r3->coeffs,0, MLKEM_N - 1, MLKEM_ETA2)); ); +#endif /* MLKEM_K == 2 */ #define poly_basemul_montgomery_cached \ MLKEM_NAMESPACE(poly_basemul_montgomery_cached) diff --git a/test/bench_components_mlkem.c b/test/bench_components_mlkem.c index b3956171c..ceb517d84 100644 --- a/test/bench_components_mlkem.c +++ b/test/bench_components_mlkem.c @@ -107,15 +107,19 @@ static int bench(void) (poly *)data3, (uint8_t *)data4, nonce0, nonce1, nonce2, nonce3)) +#if MLKEM_K == 2 || MLKEM_K == 4 /* poly_getnoise_eta2 */ BENCH("poly_getnoise_eta2", poly_getnoise_eta2((poly *)data0, (uint8_t *)data1, nonce0)) +#endif +#if MLKEM_K == 2 /* poly_getnoise_eta1122_4x */ BENCH("poly_getnoise_eta1122_4x", poly_getnoise_eta1122_4x((poly *)data0, (poly *)data1, (poly *)data2, (poly *)data3, (uint8_t *)data4, nonce0, nonce1, nonce2, nonce3)) +#endif /* poly_basemul_montgomery_cached */ BENCH("poly_basemul_montgomery_cached", From d82c33e53b5dff217b077e95e9052f271a5b3811 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 06:29:32 +0000 Subject: [PATCH 11/13] Examples: Fix `custom_backend` example on big-endian targets tiny_sha3 uses a byte-reversed Keccakf1600 presentation for big endian targets, but mlkem-native's FIPS202 frontend uses the standard presentation. This commit fixes this; luckily, the fix merely involves _removing_ byte reversal functions already present in the tiny_sha3 backend implementation of the Keccakf1600 permutation. Signed-off-by: Hanno Becker --- examples/custom_backend/README.md | 6 ++ .../fips202/native/custom/src/sha3.c | 70 +++++++++++-------- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/examples/custom_backend/README.md b/examples/custom_backend/README.md index fc287a4db..dee630158 100644 --- a/examples/custom_backend/README.md +++ b/examples/custom_backend/README.md @@ -27,6 +27,12 @@ An application using mlkem-native with a custom FIPS-202 backend and custom conf 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. +## Note + +The tiny_sha3 code uses a byte-reversed presentation of the Keccakf1600 state for big-endian targets. Since +mlkem-native's FIPS202 frontend assumes a standard presentation, the corresponding byte-reversal in +[sha3.c](mlkem_native/fips202/native/custom/src/sha3.c) is removed. + ## Usage Build this example with `make build`, run with `make run`. 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 index 27213b43a..1c147c1b5 100644 --- a/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c +++ b/examples/custom_backend/mlkem_native/fips202/native/custom/src/sha3.c @@ -31,19 +31,25 @@ void sha3_keccakf(uint64_t st[25]) 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 + /* NOTE: + * This is present in the tiny_sha3 implementation because it uses + * a byte-reversed presentation of the Keccakf1600 state for big endian + * targets. mlkem-native uses the standard presentation, hence we don't + * the reversal here. */ + /* #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++) @@ -82,22 +88,28 @@ void sha3_keccakf(uint64_t st[25]) 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 + /* NOTE: + * This is present in the tiny_sha3 implementation because it uses + * a byte-reversed presentation of the Keccakf1600 state for big endian + * targets. mlkem-native uses the standard presentation, hence we don't + * the reversal here. */ + /* #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 */ From 70f039b56255a18103e3b5b58ffd515f49043f78 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 13:36:27 +0000 Subject: [PATCH 12/13] Examples: Make `all` the default target, map to `build` Signed-off-by: Hanno Becker --- examples/bring_your_own_fips202/Makefile | 3 ++- examples/custom_backend/Makefile | 3 ++- examples/mlkem_native_as_code_package/Makefile | 3 ++- examples/monolithic_build/Makefile | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/bring_your_own_fips202/Makefile b/examples/bring_your_own_fips202/Makefile index 86225aa81..1db147ef8 100644 --- a/examples/bring_your_own_fips202/Makefile +++ b/examples/bring_your_own_fips202/Makefile @@ -1,6 +1,7 @@ # (SPDX-License-Identifier: CC-BY-4.0) .PHONY: build run clean +.DEFAULT_GOAL := all # Append cross-prefix for cross compilation # Remove or ignore for native builds @@ -78,7 +79,7 @@ $(BINARY_NAME_FULL): $(ALL_SOURCE) mkdir -p $(BUILD_DIR) $(CC) $(CFLAGS) $(INC) $^ -o $@ -all: run +all: build build: $(BINARY_NAME_FULL) diff --git a/examples/custom_backend/Makefile b/examples/custom_backend/Makefile index 0f3bc8b3e..dfb7bc52b 100644 --- a/examples/custom_backend/Makefile +++ b/examples/custom_backend/Makefile @@ -1,6 +1,7 @@ # (SPDX-License-Identifier: CC-BY-4.0) .PHONY: build run clean +.DEFAULT_GOAL := all # Append cross-prefix for cross compilation # Remove or ignore for native builds @@ -77,7 +78,7 @@ $(BINARY_NAME_FULL): $(ALL_SOURCE) mkdir -p $(BUILD_DIR) $(CC) $(CFLAGS) $(INC) $^ -o $@ -all: run +all: build build: $(BINARY_NAME_FULL) diff --git a/examples/mlkem_native_as_code_package/Makefile b/examples/mlkem_native_as_code_package/Makefile index 03848ae29..ec2d8a825 100644 --- a/examples/mlkem_native_as_code_package/Makefile +++ b/examples/mlkem_native_as_code_package/Makefile @@ -1,6 +1,7 @@ # (SPDX-License-Identifier: CC-BY-4.0) .PHONY: build run clean +.DEFAULT_GOAL := all # Append cross-prefix for cross compilation # Remove or ignore for native builds @@ -75,7 +76,7 @@ $(BINARY_NAME_FULL): $(ALL_SOURCE) mkdir -p $(BUILD_DIR) $(CC) $(CFLAGS) $(INC) $^ -o $@ -all: run +all: build build: $(BINARY_NAME_FULL) diff --git a/examples/monolithic_build/Makefile b/examples/monolithic_build/Makefile index 5f8956bdd..590eb189a 100644 --- a/examples/monolithic_build/Makefile +++ b/examples/monolithic_build/Makefile @@ -1,6 +1,7 @@ # (SPDX-License-Identifier: CC-BY-4.0) .PHONY: build run clean +.DEFAULT_GOAL := all # Append cross-prefix for cross compilation # Remove or ignore for native builds @@ -73,7 +74,7 @@ $(BINARY_NAME_FULL): $(ALL_SOURCE) mkdir -p $(BUILD_DIR) $(CC) $(CFLAGS) $(INC) $^ -o $@ -all: run +all: build build: $(BINARY_NAME_FULL) From 0d32f964988b884fcd1512af3d8de05b9658e363 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 8 Jan 2025 13:55:49 +0000 Subject: [PATCH 13/13] Examples: Fix duplicates source paths Signed-off-by: Hanno Becker --- examples/bring_your_own_fips202/Makefile | 1 - examples/custom_backend/Makefile | 1 - examples/mlkem_native_as_code_package/Makefile | 1 - 3 files changed, 3 deletions(-) diff --git a/examples/bring_your_own_fips202/Makefile b/examples/bring_your_own_fips202/Makefile index 1db147ef8..8fa02d8f9 100644 --- a/examples/bring_your_own_fips202/Makefile +++ b/examples/bring_your_own_fips202/Makefile @@ -18,7 +18,6 @@ endif # 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 \ diff --git a/examples/custom_backend/Makefile b/examples/custom_backend/Makefile index dfb7bc52b..b4639f6dd 100644 --- a/examples/custom_backend/Makefile +++ b/examples/custom_backend/Makefile @@ -19,7 +19,6 @@ endif # 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) diff --git a/examples/mlkem_native_as_code_package/Makefile b/examples/mlkem_native_as_code_package/Makefile index ec2d8a825..aba45a199 100644 --- a/examples/mlkem_native_as_code_package/Makefile +++ b/examples/mlkem_native_as_code_package/Makefile @@ -19,7 +19,6 @@ endif # 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)