From ba6459061b3990514728d1a04fe58d35e75ca655 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Tue, 4 Nov 2025 09:38:04 +0800 Subject: [PATCH 1/7] Only include mld_poly_uniform_gamma1 for ML-DSA-65 ML-DSA-44 and ML-DSA_86 only use mld_poly_uniform_gamma1_4x, while ML-DSA-65 requires both mld_poly_uniform_gamma1_4x and mld_poly_uniform_gamma1. Hence, mld_poly_uniform_gamma1 should only be included in builds for ML-DSA-65 to enable marking all internal functions as static in a multi-level monobuild. Signed-off-by: Matthias J. Kannwischer --- mldsa/src/poly_kl.c | 4 +++- mldsa/src/poly_kl.h | 2 ++ proofs/cbmc/poly_uniform_gamma1/Makefile | 5 +++++ .../cbmc/poly_uniform_gamma1/poly_uniform_gamma1_harness.c | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mldsa/src/poly_kl.c b/mldsa/src/poly_kl.c index 1bc28607b..2fb191ef3 100644 --- a/mldsa/src/poly_kl.c +++ b/mldsa/src/poly_kl.c @@ -408,9 +408,10 @@ void mld_poly_uniform_eta_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2, mld_zeroize(extseed, sizeof(extseed)); } - #define POLY_UNIFORM_GAMMA1_NBLOCKS \ ((MLDSA_POLYZ_PACKEDBYTES + STREAM256_BLOCKBYTES - 1) / STREAM256_BLOCKBYTES) + +#if MLD_CONFIG_PARAMETER_SET == 65 MLD_INTERNAL_API void mld_poly_uniform_gamma1(mld_poly *a, const uint8_t seed[MLDSA_CRHBYTES], uint16_t nonce) @@ -437,6 +438,7 @@ void mld_poly_uniform_gamma1(mld_poly *a, const uint8_t seed[MLDSA_CRHBYTES], mld_zeroize(buf, sizeof(buf)); mld_zeroize(extseed, sizeof(extseed)); } +#endif /* MLD_CONFIG_PARAMETER_SET == 65 */ MLD_INTERNAL_API void mld_poly_uniform_gamma1_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2, diff --git a/mldsa/src/poly_kl.h b/mldsa/src/poly_kl.h index ebd36b3f4..6bc25a0fe 100644 --- a/mldsa/src/poly_kl.h +++ b/mldsa/src/poly_kl.h @@ -161,6 +161,7 @@ __contract__( ensures(array_abs_bound(r3->coeffs, 0, MLDSA_N, MLDSA_ETA + 1)) ); +#if MLD_CONFIG_PARAMETER_SET == 65 #define mld_poly_uniform_gamma1 MLD_NAMESPACE_KL(poly_uniform_gamma1) /************************************************* * Name: mld_poly_uniform_gamma1 @@ -183,6 +184,7 @@ __contract__( assigns(memory_slice(a, sizeof(mld_poly))) ensures(array_bound(a->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)) ); +#endif /* MLD_CONFIG_PARAMETER_SET == 65 */ #define mld_poly_uniform_gamma1_4x MLD_NAMESPACE_KL(poly_uniform_gamma1_4x) /************************************************* diff --git a/proofs/cbmc/poly_uniform_gamma1/Makefile b/proofs/cbmc/poly_uniform_gamma1/Makefile index 0d8200698..b64b1d584 100644 --- a/proofs/cbmc/poly_uniform_gamma1/Makefile +++ b/proofs/cbmc/poly_uniform_gamma1/Makefile @@ -19,7 +19,12 @@ UNWINDSET += PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c PROJECT_SOURCES += $(SRCDIR)/mldsa/src/poly_kl.c $(SRCDIR)/mldsa/src/fips202/fips202.c +# Only relevant for ML-DSA-65 +ifeq ($(MLD_CONFIG_PARAMETER_SET),65) CHECK_FUNCTION_CONTRACTS=$(MLD_NAMESPACE)poly_uniform_gamma1 +else +CHECK_FUNCTION_CONTRACTS= +endif USE_FUNCTION_CONTRACTS=$(FIPS202_NAMESPACE)shake256_init $(FIPS202_NAMESPACE)shake256_absorb $(FIPS202_NAMESPACE)shake256_finalize $(FIPS202_NAMESPACE)shake256_squeeze $(FIPS202_NAMESPACE)shake256_release $(MLD_NAMESPACE)polyz_unpack USE_FUNCTION_CONTRACTS+=mld_zeroize APPLY_LOOP_CONTRACTS=on diff --git a/proofs/cbmc/poly_uniform_gamma1/poly_uniform_gamma1_harness.c b/proofs/cbmc/poly_uniform_gamma1/poly_uniform_gamma1_harness.c index 6c0b1fe47..d09f84f1f 100644 --- a/proofs/cbmc/poly_uniform_gamma1/poly_uniform_gamma1_harness.c +++ b/proofs/cbmc/poly_uniform_gamma1/poly_uniform_gamma1_harness.c @@ -5,9 +5,12 @@ void harness(void) { +/* mld_poly_uniform_gamma1 is only defined for ML-DSA-65 */ +#if MLD_CONFIG_PARAMETER_SET == 65 mld_poly *a; const uint8_t *seed; uint16_t nonce; mld_poly_uniform_gamma1(a, seed, nonce); +#endif } From 160dd01019e6c535c58854319dc112dc1ec071da Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Sat, 1 Nov 2025 11:22:19 +0800 Subject: [PATCH 2/7] autogen: Port SCU mldsa_native.c generation script from mlkem-native This commit ports the auto-generation script for mldsa_native.c from mlkem-native. This file will be used in subsequent commits to demonstrate a monolothic build. Signed-off-by: Matthias J. Kannwischer --- BIBLIOGRAPHY.md | 18 -- examples/basic/Makefile | 8 +- mldsa/mldsa_native.c | 630 ++++++++++++++++++++++++++++++++++++++++ scripts/autogen | 412 ++++++++++++++++++++++++-- 4 files changed, 1021 insertions(+), 47 deletions(-) create mode 100644 mldsa/mldsa_native.c diff --git a/BIBLIOGRAPHY.md b/BIBLIOGRAPHY.md index 1c362d41b..3670e5545 100644 --- a/BIBLIOGRAPHY.md +++ b/BIBLIOGRAPHY.md @@ -14,8 +14,6 @@ source code and documentation. - National Institute of Standards and Technology * URL: https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements * Referenced from: - - [examples/bring_your_own_fips202/mldsa_native/src/config.h](examples/bring_your_own_fips202/mldsa_native/src/config.h) - - [examples/bring_your_own_fips202/mldsa_native/src/sign.c](examples/bring_your_own_fips202/mldsa_native/src/sign.c) - [integration/liboqs/config_aarch64.h](integration/liboqs/config_aarch64.h) - [integration/liboqs/config_c.h](integration/liboqs/config_c.h) - [integration/liboqs/config_x86_64.h](integration/liboqs/config_x86_64.h) @@ -47,16 +45,6 @@ source code and documentation. * URL: https://csrc.nist.gov/pubs/fips/204/final * Referenced from: - [README.md](README.md) - - [examples/bring_your_own_fips202/mldsa_native/mldsa_native.h](examples/bring_your_own_fips202/mldsa_native/mldsa_native.h) - - [examples/bring_your_own_fips202/mldsa_native/src/config.h](examples/bring_your_own_fips202/mldsa_native/src/config.h) - - [examples/bring_your_own_fips202/mldsa_native/src/ct.h](examples/bring_your_own_fips202/mldsa_native/src/ct.h) - - [examples/bring_your_own_fips202/mldsa_native/src/ntt.h](examples/bring_your_own_fips202/mldsa_native/src/ntt.h) - - [examples/bring_your_own_fips202/mldsa_native/src/poly.c](examples/bring_your_own_fips202/mldsa_native/src/poly.c) - - [examples/bring_your_own_fips202/mldsa_native/src/poly_kl.c](examples/bring_your_own_fips202/mldsa_native/src/poly_kl.c) - - [examples/bring_your_own_fips202/mldsa_native/src/polyvec.c](examples/bring_your_own_fips202/mldsa_native/src/polyvec.c) - - [examples/bring_your_own_fips202/mldsa_native/src/rounding.h](examples/bring_your_own_fips202/mldsa_native/src/rounding.h) - - [examples/bring_your_own_fips202/mldsa_native/src/sign.c](examples/bring_your_own_fips202/mldsa_native/src/sign.c) - - [examples/bring_your_own_fips202/mldsa_native/src/sign.h](examples/bring_your_own_fips202/mldsa_native/src/sign.h) - [mldsa/mldsa_native.h](mldsa/mldsa_native.h) - [mldsa/src/config.h](mldsa/src/config.h) - [mldsa/src/ct.h](mldsa/src/ct.h) @@ -159,9 +147,6 @@ source code and documentation. * URL: https://github.com/pq-crystals/dilithium/tree/master/ref * Referenced from: - [README.md](README.md) - - [examples/bring_your_own_fips202/mldsa_native/src/ntt.c](examples/bring_your_own_fips202/mldsa_native/src/ntt.c) - - [examples/bring_your_own_fips202/mldsa_native/src/poly.c](examples/bring_your_own_fips202/mldsa_native/src/poly.c) - - [examples/bring_your_own_fips202/mldsa_native/src/poly_kl.c](examples/bring_your_own_fips202/mldsa_native/src/poly_kl.c) - [mldsa/src/ntt.c](mldsa/src/ntt.c) - [mldsa/src/poly.c](mldsa/src/poly.c) - [mldsa/src/poly_kl.c](mldsa/src/poly_kl.c) @@ -237,7 +222,6 @@ source code and documentation. - Damien Stehlé * URL: https://pq-crystals.org/dilithium/data/dilithium-specification-round3-20210208.pdf * Referenced from: - - [examples/bring_your_own_fips202/mldsa_native/src/sign.c](examples/bring_your_own_fips202/mldsa_native/src/sign.c) - [mldsa/src/sign.c](mldsa/src/sign.c) ### `SLOTHY_Paper` @@ -263,7 +247,6 @@ source code and documentation. - Tung Chou * URL: https://lib.mceliece.org/ * Referenced from: - - [examples/bring_your_own_fips202/mldsa_native/src/ct.h](examples/bring_your_own_fips202/mldsa_native/src/ct.h) - [mldsa/src/ct.h](mldsa/src/ct.h) ### `m1cycles` @@ -296,7 +279,6 @@ source code and documentation. - Daniel J. Bernstein * URL: https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/hqbtIGFKIpU/m/H14H0wOlBgAJ * Referenced from: - - [examples/bring_your_own_fips202/mldsa_native/src/ct.h](examples/bring_your_own_fips202/mldsa_native/src/ct.h) - [mldsa/src/ct.h](mldsa/src/ct.h) ### `supercop` diff --git a/examples/basic/Makefile b/examples/basic/Makefile index 492bb9345..e51566645 100644 --- a/examples/basic/Makefile +++ b/examples/basic/Makefile @@ -56,10 +56,10 @@ endif # Alternatively, you can compile the 'monobuild' source file mldsa_native.c. # See examples/monolithic_build for that. MLD_SOURCE=$(wildcard \ - mldsa_native/mldsa/*.c \ - mldsa_native/mldsa/**/*.c \ - mldsa_native/mldsa/**/**/*.c \ - mldsa_native/mldsa/**/**/**/*.c) + mldsa_native/mldsa/src/*.c \ + mldsa_native/mldsa/src/**/*.c \ + mldsa_native/mldsa/src/**/**/*.c \ + mldsa_native/mldsa/src/**/**/**/*.c) INC=-Imldsa_native/mldsa/ diff --git a/mldsa/mldsa_native.c b/mldsa/mldsa_native.c new file mode 100644 index 000000000..c34076985 --- /dev/null +++ b/mldsa/mldsa_native.c @@ -0,0 +1,630 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +/* + * WARNING: This file is auto-generated from scripts/autogen + * in the mldsa-native repository. + * Do not modify it directly. + */ + +/****************************************************************************** + * + * Single compilation unit (SCU) for fixed-level build of mldsa-native + * + * This compilation unit bundles together all source files for a build + * of mldsa-native for a fixed security level (MLDSA-44/65/87). + * + * # API + * + * The API exposed by this file is described in mldsa_native.h. + * + * # Multi-level build + * + * If you want an SCU build of mldsa-native with support for multiple security + * levels, you need to include this file multiple times, and set + * MLD_CONFIG_MULTILEVEL_WITH_SHARED and MLD_CONFIG_MULTILEVEL_NO_SHARED + * appropriately. This is exemplified in examples/monolithic_build_multilevel + * and examples/monolithic_build_multilevel_native. + * + * # Configuration + * + * The following options from the mldsa-native configuration are relevant: + * + * - MLD_CONFIG_FIPS202_CUSTOM_HEADER + * Set this option if you use a custom FIPS202 implementation. + * + * - MLD_CONFIG_USE_NATIVE_BACKEND_ARITH + * Set this option if you want to include the native arithmetic backends + * in your build. + * + * - MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 + * Set this option if you want to include the native FIPS202 backends + * in your build. + * + * - MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS + * Set this option if you want to keep the directives defined in + * level-independent headers. This is needed for a multi-level build. + */ + +/* If parts of the mldsa-native source tree are not used, + * consider reducing this header via `unifdef`. + * + * Example: + * ```bash + * unifdef -UMLD_CONFIG_USE_NATIVE_BACKEND_ARITH mldsa_native.c + * ``` + */ + +#include "src/common.h" + +#include "src/ct.c" +#include "src/debug.c" +#include "src/ntt.c" +#include "src/packing.c" +#include "src/poly.c" +#include "src/poly_kl.c" +#include "src/polyvec.c" +#include "src/prehash.c" +#include "src/sign.c" + +#if !defined(MLD_CONFIG_FIPS202_CUSTOM_HEADER) +#include "src/fips202/fips202.c" +#include "src/fips202/fips202x4.c" +#include "src/fips202/keccakf1600.c" +#endif + +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) +#if defined(MLD_SYS_AARCH64) +#include "src/native/aarch64/src/aarch64_zetas.c" +#include "src/native/aarch64/src/polyz_unpack_table.c" +#include "src/native/aarch64/src/rej_uniform_eta_table.c" +#include "src/native/aarch64/src/rej_uniform_table.c" +#endif /* MLD_SYS_AARCH64 */ +#if defined(MLD_SYS_X86_64) +#include "src/native/x86_64/src/consts.c" +#include "src/native/x86_64/src/poly_caddq_avx2.c" +#include "src/native/x86_64/src/poly_chknorm_avx2.c" +#include "src/native/x86_64/src/poly_decompose_32_avx2.c" +#include "src/native/x86_64/src/poly_decompose_88_avx2.c" +#include "src/native/x86_64/src/poly_use_hint_32_avx2.c" +#include "src/native/x86_64/src/poly_use_hint_88_avx2.c" +#include "src/native/x86_64/src/polyz_unpack_17_avx2.c" +#include "src/native/x86_64/src/polyz_unpack_19_avx2.c" +#include "src/native/x86_64/src/rej_uniform_avx2.c" +#include "src/native/x86_64/src/rej_uniform_eta2_avx2.c" +#include "src/native/x86_64/src/rej_uniform_eta4_avx2.c" +#include "src/native/x86_64/src/rej_uniform_table.c" +#endif /* MLD_SYS_X86_64 */ +#endif /* MLD_CONFIG_USE_NATIVE_BACKEND_ARITH */ + +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202) +#if defined(MLD_SYS_AARCH64) +#include "src/fips202/native/aarch64/src/keccakf1600_round_constants.c" +#endif +#if defined(MLD_SYS_X86_64) +#include "src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.c" +#endif +#endif /* MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 */ + +/* Macro #undef's + * + * The following undefines macros from headers + * included by the source files imported above. + * + * This is to allow building and linking multiple builds + * of mldsa-native for varying parameter sets through concatenation + * of this file, as if the files had been compiled separately. + * If this is not relevant to you, you may remove the following. + */ + +/* + * Undefine macros from MLD_CONFIG_PARAMETER_SET-specific files + */ +/* mldsa/mldsa_native.h */ +#undef CRYPTO_BYTES +#undef CRYPTO_PUBLICKEYBYTES +#undef CRYPTO_SECRETKEYBYTES +#undef MLDSA44_BYTES +#undef MLDSA44_CRHBYTES +#undef MLDSA44_PUBLICKEYBYTES +#undef MLDSA44_RNDBYTES +#undef MLDSA44_SECRETKEYBYTES +#undef MLDSA44_SEEDBYTES +#undef MLDSA44_TRBYTES +#undef MLDSA65_BYTES +#undef MLDSA65_CRHBYTES +#undef MLDSA65_PUBLICKEYBYTES +#undef MLDSA65_RNDBYTES +#undef MLDSA65_SECRETKEYBYTES +#undef MLDSA65_SEEDBYTES +#undef MLDSA65_TRBYTES +#undef MLDSA87_BYTES +#undef MLDSA87_CRHBYTES +#undef MLDSA87_PUBLICKEYBYTES +#undef MLDSA87_RNDBYTES +#undef MLDSA87_SECRETKEYBYTES +#undef MLDSA87_SEEDBYTES +#undef MLDSA87_TRBYTES +#undef MLDSA_BYTES +#undef MLDSA_BYTES_ +#undef MLDSA_CRHBYTES +#undef MLDSA_PUBLICKEYBYTES +#undef MLDSA_PUBLICKEYBYTES_ +#undef MLDSA_RNDBYTES +#undef MLDSA_SECRETKEYBYTES +#undef MLDSA_SECRETKEYBYTES_ +#undef MLDSA_SEEDBYTES +#undef MLDSA_TRBYTES +#undef MLD_API_CONCAT +#undef MLD_API_CONCAT_ +#undef MLD_API_CONCAT_UNDERSCORE +#undef MLD_API_MUST_CHECK_RETURN_VALUE +#undef MLD_API_NAMESPACE +#undef MLD_H +#undef MLD_PRE_HASH_ENUM +#undef crypto_sign +#undef crypto_sign_keypair +#undef crypto_sign_open +#undef crypto_sign_signature +#undef crypto_sign_verify +/* mldsa/src/common.h */ +#undef MLD_ADD_PARAM_SET +#undef MLD_ASM_FN_SYMBOL +#undef MLD_ASM_NAMESPACE +#undef MLD_COMMON_H +#undef MLD_CONCAT +#undef MLD_CONCAT_ +#undef MLD_EMPTY_CU +#undef MLD_EXTERNAL_API +#undef MLD_FIPS202X4_HEADER_FILE +#undef MLD_FIPS202_HEADER_FILE +#undef MLD_INTERNAL_API +#undef MLD_MULTILEVEL_BUILD +#undef MLD_NAMESPACE +#undef MLD_NAMESPACE_KL +#undef MLD_NAMESPACE_PREFIX +#undef MLD_NAMESPACE_PREFIX_KL +#undef mld_memcpy +#undef mld_memset +/* mldsa/src/packing.h */ +#undef MLD_PACKING_H +#undef mld_pack_pk +#undef mld_pack_sig +#undef mld_pack_sk +#undef mld_unpack_pk +#undef mld_unpack_sig +#undef mld_unpack_sk +/* mldsa/src/params.h */ +#undef CRYPTO_BYTES +#undef CRYPTO_PUBLICKEYBYTES +#undef CRYPTO_SECRETKEYBYTES +#undef MLDSA_BETA +#undef MLDSA_CRHBYTES +#undef MLDSA_CTILDEBYTES +#undef MLDSA_D +#undef MLDSA_ETA +#undef MLDSA_GAMMA1 +#undef MLDSA_GAMMA2 +#undef MLDSA_K +#undef MLDSA_L +#undef MLDSA_N +#undef MLDSA_OMEGA +#undef MLDSA_POLYETA_PACKEDBYTES +#undef MLDSA_POLYT0_PACKEDBYTES +#undef MLDSA_POLYT1_PACKEDBYTES +#undef MLDSA_POLYVECH_PACKEDBYTES +#undef MLDSA_POLYW1_PACKEDBYTES +#undef MLDSA_POLYZ_PACKEDBYTES +#undef MLDSA_Q +#undef MLDSA_Q_HALF +#undef MLDSA_RNDBYTES +#undef MLDSA_SEEDBYTES +#undef MLDSA_TAU +#undef MLDSA_TRBYTES +#undef MLD_PARAMS_H +/* mldsa/src/poly_kl.h */ +#undef MLD_POLYETA_UNPACK_LOWER_BOUND +#undef MLD_POLY_KL_H +#undef mld_poly_challenge +#undef mld_poly_chknorm +#undef mld_poly_decompose +#undef mld_poly_make_hint +#undef mld_poly_uniform_eta_4x +#undef mld_poly_uniform_gamma1 +#undef mld_poly_uniform_gamma1_4x +#undef mld_poly_use_hint +#undef mld_polyeta_pack +#undef mld_polyeta_unpack +#undef mld_polyw1_pack +#undef mld_polyz_pack +#undef mld_polyz_unpack +/* mldsa/src/polyvec.h */ +#undef MLD_POLYVEC_H +#undef mld_polyvec_matrix_expand +#undef mld_polyvec_matrix_pointwise_montgomery +#undef mld_polyveck +#undef mld_polyveck_add +#undef mld_polyveck_caddq +#undef mld_polyveck_chknorm +#undef mld_polyveck_decompose +#undef mld_polyveck_invntt_tomont +#undef mld_polyveck_make_hint +#undef mld_polyveck_ntt +#undef mld_polyveck_pack_eta +#undef mld_polyveck_pack_t0 +#undef mld_polyveck_pack_w1 +#undef mld_polyveck_pointwise_poly_montgomery +#undef mld_polyveck_power2round +#undef mld_polyveck_reduce +#undef mld_polyveck_shiftl +#undef mld_polyveck_sub +#undef mld_polyveck_unpack_eta +#undef mld_polyveck_unpack_t0 +#undef mld_polyveck_use_hint +#undef mld_polyvecl +#undef mld_polyvecl_add +#undef mld_polyvecl_chknorm +#undef mld_polyvecl_invntt_tomont +#undef mld_polyvecl_ntt +#undef mld_polyvecl_pack_eta +#undef mld_polyvecl_pack_z +#undef mld_polyvecl_pointwise_acc_montgomery +#undef mld_polyvecl_pointwise_poly_montgomery +#undef mld_polyvecl_reduce +#undef mld_polyvecl_uniform_gamma1 +#undef mld_polyvecl_unpack_eta +#undef mld_polyvecl_unpack_z +/* mldsa/src/rounding.h */ +#undef MLD_2_POW_D +#undef MLD_ROUNDING_H +#undef mld_decompose +#undef mld_make_hint +#undef mld_power2round +#undef mld_use_hint +/* mldsa/src/sign.h */ +#undef MLD_SIGN_H +#undef crypto_sign +#undef crypto_sign_keypair +#undef crypto_sign_keypair_internal +#undef crypto_sign_open +#undef crypto_sign_signature +#undef crypto_sign_signature_extmu +#undef crypto_sign_signature_internal +#undef crypto_sign_signature_pre_hash_internal +#undef crypto_sign_signature_pre_hash_shake256 +#undef crypto_sign_verify +#undef crypto_sign_verify_extmu +#undef crypto_sign_verify_internal +#undef crypto_sign_verify_pre_hash_internal +#undef crypto_sign_verify_pre_hash_shake256 + +#if !defined(MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS) +/* + * Undefine macros from MLD_CONFIG_PARAMETER_SET-generic files + */ +/* mldsa/src/ct.h */ +#undef MLD_CT_H +#undef MLD_USE_ASM_VALUE_BARRIER +#undef mld_ct_opt_blocker_u64 +/* mldsa/src/debug.h */ +#undef MLD_DEBUG_H +#undef mld_assert +#undef mld_assert_abs_bound +#undef mld_assert_abs_bound_2d +#undef mld_assert_bound +#undef mld_assert_bound_2d +#undef mld_debug_check_assert +#undef mld_debug_check_bounds +/* mldsa/src/ntt.h */ +#undef MLD_INTT_BOUND +#undef MLD_NTT_BOUND +#undef MLD_NTT_H +#undef mld_invntt_tomont +#undef mld_ntt +/* mldsa/src/poly.h */ +#undef MLD_POLY_H +#undef mld_poly_add +#undef mld_poly_caddq +#undef mld_poly_invntt_tomont +#undef mld_poly_ntt +#undef mld_poly_pointwise_montgomery +#undef mld_poly_power2round +#undef mld_poly_reduce +#undef mld_poly_shiftl +#undef mld_poly_sub +#undef mld_poly_uniform +#undef mld_poly_uniform_4x +#undef mld_polyt0_pack +#undef mld_polyt0_unpack +#undef mld_polyt1_pack +#undef mld_polyt1_unpack +/* mldsa/src/prehash.h */ +#undef MLD_PREHASH_H +#undef MLD_PRE_HASH_MAX_FORMATTED_MESSAGE_BYTES +#undef mld_format_pre_hash_message +#undef mld_validate_hash_length +/* mldsa/src/randombytes.h */ +#undef MLD_RANDOMBYTES_H +/* mldsa/src/reduce.h */ +#undef MLD_REDUCE_H +#undef MONT +#undef MONTGOMERY_REDUCE_DOMAIN_MAX +#undef MONTGOMERY_REDUCE_STRONG_DOMAIN_MAX +#undef REDUCE32_DOMAIN_MAX +#undef REDUCE32_RANGE_MAX +/* mldsa/src/symmetric.h */ +#undef MLD_SYMMETRIC_H +#undef STREAM128_BLOCKBYTES +#undef STREAM256_BLOCKBYTES +#undef mld_xof128_absorb_once +#undef mld_xof128_ctx +#undef mld_xof128_init +#undef mld_xof128_release +#undef mld_xof128_squeezeblocks +#undef mld_xof128_x4_absorb +#undef mld_xof128_x4_ctx +#undef mld_xof128_x4_init +#undef mld_xof128_x4_release +#undef mld_xof128_x4_squeezeblocks +#undef mld_xof256_absorb_once +#undef mld_xof256_ctx +#undef mld_xof256_init +#undef mld_xof256_release +#undef mld_xof256_squeezeblocks +#undef mld_xof256_x4_absorb +#undef mld_xof256_x4_ctx +#undef mld_xof256_x4_init +#undef mld_xof256_x4_release +#undef mld_xof256_x4_squeezeblocks +/* mldsa/src/sys.h */ +#undef MLD_ALIGN +#undef MLD_ALIGN_UP +#undef MLD_ALWAYS_INLINE +#undef MLD_CET_ENDBR +#undef MLD_CT_TESTING_DECLASSIFY +#undef MLD_CT_TESTING_SECRET +#undef MLD_DEFAULT_ALIGN +#undef MLD_HAVE_INLINE_ASM +#undef MLD_INLINE +#undef MLD_MUST_CHECK_RETURN_VALUE +#undef MLD_RESTRICT +#undef MLD_SYS_AARCH64 +#undef MLD_SYS_AARCH64_EB +#undef MLD_SYS_BIG_ENDIAN +#undef MLD_SYS_H +#undef MLD_SYS_LITTLE_ENDIAN +#undef MLD_SYS_PPC64LE +#undef MLD_SYS_RISCV64 +#undef MLD_SYS_WINDOWS +#undef MLD_SYS_X86_64 +#undef MLD_SYS_X86_64_AVX2 +/* mldsa/src/cbmc.h */ +#undef MLD_CBMC_H +#undef __contract__ +#undef __loop__ + +#if !defined(MLD_CONFIG_FIPS202_CUSTOM_HEADER) +/* + * Undefine macros from FIPS-202 files + */ +/* mldsa/src/fips202/fips202.h */ +#undef FIPS202_NAMESPACE +#undef MLD_FIPS202_FIPS202_H +#undef MLD_KECCAK_LANES +#undef SHA3_256_HASHBYTES +#undef SHA3_256_RATE +#undef SHA3_512_HASHBYTES +#undef SHA3_512_RATE +#undef SHAKE128_RATE +#undef SHAKE256_RATE +#undef mld_shake128_absorb +#undef mld_shake128_finalize +#undef mld_shake128_init +#undef mld_shake128_release +#undef mld_shake128_squeeze +#undef mld_shake256 +#undef mld_shake256_absorb +#undef mld_shake256_finalize +#undef mld_shake256_init +#undef mld_shake256_release +#undef mld_shake256_squeeze +/* mldsa/src/fips202/fips202x4.h */ +#undef MLD_FIPS202_FIPS202X4_H +#undef mld_shake128x4_absorb_once +#undef mld_shake128x4_init +#undef mld_shake128x4_release +#undef mld_shake128x4_squeezeblocks +#undef mld_shake256x4_absorb_once +#undef mld_shake256x4_init +#undef mld_shake256x4_release +#undef mld_shake256x4_squeezeblocks +/* mldsa/src/fips202/keccakf1600.h */ +#undef MLD_FIPS202_KECCAKF1600_H +#undef MLD_KECCAK_LANES +#undef MLD_KECCAK_WAY +#undef mld_keccakf1600_extract_bytes +#undef mld_keccakf1600_permute +#undef mld_keccakf1600_xor_bytes +#undef mld_keccakf1600x4_extract_bytes +#undef mld_keccakf1600x4_permute +#undef mld_keccakf1600x4_xor_bytes +#endif /* !MLD_CONFIG_FIPS202_CUSTOM_HEADER */ + +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202) +/* mldsa/src/fips202/native/api.h */ +#undef MLD_FIPS202_NATIVE_API_H +/* mldsa/src/fips202/native/auto.h */ +#undef MLD_FIPS202_NATIVE_AUTO_H +#if defined(MLD_SYS_AARCH64) +/* + * Undefine macros from native code (FIPS202, AArch64) + */ +/* mldsa/src/fips202/native/aarch64/auto.h */ +#undef MLD_FIPS202_NATIVE_AARCH64_AUTO_H +/* mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h */ +#undef MLD_FIPS202_NATIVE_AARCH64_SRC_FIPS202_NATIVE_AARCH64_H +#undef mld_keccak_f1600_x1_scalar_asm +#undef mld_keccak_f1600_x1_v84a_asm +#undef mld_keccak_f1600_x2_v84a_asm +#undef mld_keccak_f1600_x4_scalar_v8a_hybrid_asm +#undef mld_keccak_f1600_x4_scalar_v8a_v84a_hybrid_asm +#undef mld_keccakf1600_round_constants +/* mldsa/src/fips202/native/aarch64/x1_scalar.h */ +#undef MLD_FIPS202_AARCH64_NEED_X1_SCALAR +#undef MLD_FIPS202_NATIVE_AARCH64_X1_SCALAR_H +#undef MLD_USE_FIPS202_X1_NATIVE +/* mldsa/src/fips202/native/aarch64/x1_v84a.h */ +#undef MLD_FIPS202_AARCH64_NEED_X1_V84A +#undef MLD_FIPS202_NATIVE_AARCH64_X1_V84A_H +#undef MLD_USE_FIPS202_X1_NATIVE +/* mldsa/src/fips202/native/aarch64/x2_v84a.h */ +#undef MLD_FIPS202_AARCH64_NEED_X2_V84A +#undef MLD_FIPS202_NATIVE_AARCH64_X2_V84A_H +#undef MLD_USE_FIPS202_X2_NATIVE +/* mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h */ +#undef MLD_FIPS202_AARCH64_NEED_X4_V8A_SCALAR_HYBRID +#undef MLD_FIPS202_NATIVE_AARCH64_X4_V8A_SCALAR_H +#undef MLD_USE_FIPS202_X4_NATIVE +/* mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h */ +#undef MLD_FIPS202_AARCH64_NEED_X4_V8A_V84A_SCALAR_HYBRID +#undef MLD_FIPS202_NATIVE_AARCH64_X4_V8A_V84A_SCALAR_H +#undef MLD_USE_FIPS202_X4_NATIVE +#endif /* MLD_SYS_AARCH64 */ +#if defined(MLD_SYS_X86_64) +/* + * Undefine macros from native code (FIPS202, x86_64) + */ +/* mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.h */ +#undef MLD_FIPS202_NATIVE_X86_64_SRC_KECCAKP_1600_TIMES4_SIMD256_H +#undef mld_keccakf1600x4_permute24 +/* mldsa/src/fips202/native/x86_64/xkcp.h */ +#undef MLD_FIPS202_NATIVE_X86_64_XKCP_H +#undef MLD_FIPS202_X86_64_XKCP +#undef MLD_USE_FIPS202_X4_NATIVE +#endif /* MLD_SYS_X86_64 */ +#endif /* MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 */ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) +/* mldsa/src/native/api.h */ +#undef MLD_NATIVE_API_H +/* mldsa/src/native/meta.h */ +#undef MLD_NATIVE_META_H +#if defined(MLD_SYS_AARCH64) +/* + * Undefine macros from native code (Arith, AArch64) + */ +/* mldsa/src/native/aarch64/meta.h */ +#undef MLD_ARITH_BACKEND_AARCH64 +#undef MLD_NATIVE_AARCH64_META_H +#undef MLD_USE_NATIVE_INTT +#undef MLD_USE_NATIVE_NTT +#undef MLD_USE_NATIVE_POINTWISE_MONTGOMERY +#undef MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L4 +#undef MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 +#undef MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 +#undef MLD_USE_NATIVE_POLYZ_UNPACK_17 +#undef MLD_USE_NATIVE_POLYZ_UNPACK_19 +#undef MLD_USE_NATIVE_POLY_CADDQ +#undef MLD_USE_NATIVE_POLY_CHKNORM +#undef MLD_USE_NATIVE_POLY_DECOMPOSE_32 +#undef MLD_USE_NATIVE_POLY_DECOMPOSE_88 +#undef MLD_USE_NATIVE_POLY_USE_HINT_32 +#undef MLD_USE_NATIVE_POLY_USE_HINT_88 +#undef MLD_USE_NATIVE_REJ_UNIFORM +#undef MLD_USE_NATIVE_REJ_UNIFORM_ETA2 +#undef MLD_USE_NATIVE_REJ_UNIFORM_ETA4 +/* mldsa/src/native/aarch64/src/arith_native_aarch64.h */ +#undef MLD_AARCH64_REJ_UNIFORM_ETA2_BUFLEN +#undef MLD_AARCH64_REJ_UNIFORM_ETA4_BUFLEN +#undef MLD_NATIVE_AARCH64_SRC_ARITH_NATIVE_AARCH64_H +#undef mld_aarch64_intt_zetas_layer123456 +#undef mld_aarch64_intt_zetas_layer78 +#undef mld_aarch64_ntt_zetas_layer123456 +#undef mld_aarch64_ntt_zetas_layer78 +#undef mld_intt_asm +#undef mld_ntt_asm +#undef mld_poly_caddq_asm +#undef mld_poly_chknorm_asm +#undef mld_poly_decompose_32_asm +#undef mld_poly_decompose_88_asm +#undef mld_poly_pointwise_montgomery_asm +#undef mld_poly_use_hint_32_asm +#undef mld_poly_use_hint_88_asm +#undef mld_polyvecl_pointwise_acc_montgomery_l4_asm +#undef mld_polyvecl_pointwise_acc_montgomery_l5_asm +#undef mld_polyvecl_pointwise_acc_montgomery_l7_asm +#undef mld_polyz_unpack_17_asm +#undef mld_polyz_unpack_17_indices +#undef mld_polyz_unpack_19_asm +#undef mld_polyz_unpack_19_indices +#undef mld_rej_uniform_asm +#undef mld_rej_uniform_eta2_asm +#undef mld_rej_uniform_eta4_asm +#undef mld_rej_uniform_eta_table +#undef mld_rej_uniform_table +#endif /* MLD_SYS_AARCH64 */ +#if defined(MLD_SYS_X86_64) +/* + * Undefine macros from native code (Arith, X86_64) + */ +/* mldsa/src/native/x86_64/meta.h */ +#undef MLD_ARITH_BACKEND_X86_64_DEFAULT +#undef MLD_NATIVE_X86_64_META_H +#undef MLD_USE_NATIVE_INTT +#undef MLD_USE_NATIVE_NTT +#undef MLD_USE_NATIVE_NTT_CUSTOM_ORDER +#undef MLD_USE_NATIVE_POINTWISE_MONTGOMERY +#undef MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L4 +#undef MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 +#undef MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 +#undef MLD_USE_NATIVE_POLYZ_UNPACK_17 +#undef MLD_USE_NATIVE_POLYZ_UNPACK_19 +#undef MLD_USE_NATIVE_POLY_CADDQ +#undef MLD_USE_NATIVE_POLY_CHKNORM +#undef MLD_USE_NATIVE_POLY_DECOMPOSE_32 +#undef MLD_USE_NATIVE_POLY_DECOMPOSE_88 +#undef MLD_USE_NATIVE_POLY_USE_HINT_32 +#undef MLD_USE_NATIVE_POLY_USE_HINT_88 +#undef MLD_USE_NATIVE_REJ_UNIFORM +#undef MLD_USE_NATIVE_REJ_UNIFORM_ETA2 +#undef MLD_USE_NATIVE_REJ_UNIFORM_ETA4 +/* mldsa/src/native/x86_64/src/align.h */ +#undef MLD_ALIGNED_INT32 +#undef MLD_NATIVE_X86_64_SRC_ALIGN_H +/* mldsa/src/native/x86_64/src/arith_native_x86_64.h */ +#undef MLD_AVX2_REJ_UNIFORM_BUFLEN +#undef MLD_AVX2_REJ_UNIFORM_ETA2_BUFLEN +#undef MLD_AVX2_REJ_UNIFORM_ETA4_BUFLEN +#undef MLD_NATIVE_X86_64_SRC_ARITH_NATIVE_X86_64_H +#undef mld_invntt_avx2 +#undef mld_ntt_avx2 +#undef mld_nttunpack_avx2 +#undef mld_pointwise_acc_l4_avx2 +#undef mld_pointwise_acc_l5_avx2 +#undef mld_pointwise_acc_l7_avx2 +#undef mld_pointwise_avx2 +#undef mld_poly_caddq_avx2 +#undef mld_poly_chknorm_avx2 +#undef mld_poly_decompose_32_avx2 +#undef mld_poly_decompose_88_avx2 +#undef mld_poly_use_hint_32_avx2 +#undef mld_poly_use_hint_88_avx2 +#undef mld_polyz_unpack_17_avx2 +#undef mld_polyz_unpack_19_avx2 +#undef mld_rej_uniform_avx2 +#undef mld_rej_uniform_eta2_avx2 +#undef mld_rej_uniform_eta4_avx2 +#undef mld_rej_uniform_table +/* mldsa/src/native/x86_64/src/consts.h */ +#undef MLD_AVX2_BACKEND_DATA_OFFSET_8XDIV +#undef MLD_AVX2_BACKEND_DATA_OFFSET_8XDIV_QINV +#undef MLD_AVX2_BACKEND_DATA_OFFSET_8XQ +#undef MLD_AVX2_BACKEND_DATA_OFFSET_8XQINV +#undef MLD_AVX2_BACKEND_DATA_OFFSET_ZETAS +#undef MLD_AVX2_BACKEND_DATA_OFFSET_ZETAS_QINV +#undef MLD_NATIVE_X86_64_SRC_CONSTS_H +#undef mld_qdata +#endif /* MLD_SYS_X86_64 */ +#endif /* MLD_CONFIG_USE_NATIVE_BACKEND_ARITH */ +#endif /* !MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS */ diff --git a/scripts/autogen b/scripts/autogen index f1105e946..aa70fbf3d 100755 --- a/scripts/autogen +++ b/scripts/autogen @@ -93,31 +93,6 @@ def gen_yaml_header(): yield "" -def get_files(pattern): - return [str(p) for p in pathlib.Path().glob(pattern) if p.is_file()] - - -def get_c_source_files(main_only=False): - if main_only is True: - return get_files("mldsa/**/*.c") - else: - return get_files("**/*.c") - - -def get_asm_source_files(main_only=False): - if main_only is True: - return get_files("mldsa/**/*.S") - else: - return get_files("**/*.S") - - -def get_header_files(main_only=False): - if main_only is True: - return get_files("mldsa/**/*.h") - else: - return get_files("**/*.h") - - def format_content(content): p = subprocess.run( ["clang-format"], capture_output=True, input=content, text=True, shell=True @@ -1009,6 +984,391 @@ def gen_avx2_zeta_file(dry_run=False): update_file("dev/x86_64/src/x86_64_zetas.i", "\n".join(gen()), dry_run=dry_run) +def get_c_source_files(main_only=False, core_only=False, strip_mldsa=False): + if main_only is True: + return get_files("mldsa/src/**/*.c", strip_mldsa=strip_mldsa) + elif core_only is True: + return get_files("mldsa/src/**/*.c", strip_mldsa=strip_mldsa) + get_files( + "dev/**/*.c" + ) + else: + return get_files("**/*.c", strip_mldsa=strip_mldsa) + + +def get_asm_source_files(main_only=False, core_only=False, strip_mldsa=False): + if main_only is True: + return get_files("mldsa/src/**/*.S", strip_mldsa=strip_mldsa) + elif core_only is True: + return get_files("mldsa/src/**/*.S", strip_mldsa=strip_mldsa) + get_files( + "dev/**/*.S", strip_mldsa=strip_mldsa + ) + else: + return get_files("**/*.S", strip_mldsa=strip_mldsa) + + +def get_header_files(main_only=False, core_only=False): + if main_only is True: + return get_files("mldsa/*.h") + get_files("mldsa/src/**/*.h") + elif core_only is True: + return ( + get_files("mldsa/*.h") + + get_files("mldsa/src/**/*.h") + + get_files("dev/**/*.h") + + get_files("integration/**/*.h") + ) + else: + return get_files("**/*.h") + + +def get_markdown_files(main_only=False): + return get_files("**/*.md") + + +def get_files(pattern, strip_mldsa=False): + return [ + str(p).removeprefix("mldsa/") if strip_mldsa else str(p) + for p in pathlib.Path().glob(pattern) + if p.is_file() and not p.is_symlink() + ] + + +def get_all_files(): + # All git-tracked files, including symlinks + r = subprocess.run(["git", "ls-files"], capture_output=True, text=True) + assert r.returncode == 0 + files = r.stdout.split("\n") + files = filter(lambda s: s != "" and pathlib.Path(s).is_symlink() is False, files) + return files + + +def get_defines_from_file(c): + with open(c, "r") as f: + for l in f.read().split("\n"): + if l.lstrip().startswith("#define "): + yield ( + c, + l.lstrip() + .removeprefix("#define ") + .split(" ")[0] + .split("(")[0] + .replace("'", ""), + ) + + +def get_defines(all=False): + if all is False: + files = get_header_files(main_only=True) + else: + files = get_header_files() + get_c_source_files() + get_asm_source_files() + for c in files: + yield from get_defines_from_file(c) + + +def get_checked_defines(): + allow_list = [("__contract__", "cbmc.h"), ("__loop__", "cbmc.h")] + + def is_allowed(d, c): + for d0, c0 in allow_list: + if c.endswith(c0) is True and d0 == d: + return True + return False + + for c, d in get_defines(): + if d.startswith("_") and is_allowed(d, c) is False: + raise Exception( + f"{d} from {c}: starts with an underscore, which is not allowed for mldsa-native macros. " + f"If this is an mldsa-native specific macro, please pick a different name. " + f"If this is an external macro, it likely needs removing from `gen_monolithic_undef_all_core()` in `scripts/autogen` -- check this!" + ) + yield (c, d) + + +def gen_monolithic_undef_all_core(filt=None, desc=""): + + if filt is None: + filt = lambda c: True + + if desc != "": + yield "/*" + yield f" * Undefine macros from {desc}" + yield " */" + + defines = list(set(get_checked_defines())) + defines.sort() + + last_filename = None + for filename, d in defines: + if filt(filename) is False: + continue + if last_filename != filename: + yield f"/* {filename} */" + last_filename = filename + yield f"#undef {d}" + + +def native(c): + return "/native/" in c + + +def fips202(c): + return "/fips202/" in c + + +def aarch64(c): + return "/aarch64/" in c + + +def x86_64(c): + return "/x86_64/" in c + + +def riscv64(c): + return "/riscv64/" in c + + +def native_fips202(c): + return native(c) and fips202(c) + + +def native_arith(c): + return native(c) and not fips202(c) + + +def native_fips202_aarch64(c): + return native_fips202(c) and aarch64(c) + + +def native_fips202_x86_64(c): + return native_fips202(c) and x86_64(c) + + +def native_fips202_core(c): + return ( + native_fips202(c) + and not native_fips202_x86_64(c) + and not native_fips202_aarch64(c) + ) + + +def native_arith_aarch64(c): + return native_arith(c) and aarch64(c) + + +def native_arith_x86_64(c): + return native_arith(c) and x86_64(c) + + +def native_arith_riscv64(c): + return native_arith(c) and riscv64(c) + + +def native_arith_core(c): + return ( + native_arith(c) + and not native_arith_x86_64(c) + and not native_arith_aarch64(c) + and not native_arith_riscv64(c) + ) + + +# List of level-specific source files +# All other files only need including and building once +# in multi-level build. +def k_specific(c): + k_specific_sources = [ + "mldsa_native.h", + "params.h", + # Deliberately omit config.h, which is not #undef'ed + "common.h", + "packing.c", + "packing.h", + "poly_kl.c", + "poly_kl.h", + "polyvec.c", + "polyvec.h", + "rounding.h", + "sign.c", + "sign.h", + ] + for f in k_specific_sources: + if c.endswith(f): + return True + return False + + +def k_generic(c): + return not k_specific(c) and c != "mldsa/src/config.h" + + +def gen_macro_undefs(extra_notes=None): + if extra_notes is None: + extra_notes = [] + + yield "/* Macro #undef's" + yield " *" + yield " * The following undefines macros from headers" + yield " * included by the source files imported above." + yield " *" + yield " * This is to allow building and linking multiple builds" + yield " * of mldsa-native for varying parameter sets through concatenation" + yield " * of this file, as if the files had been compiled separately." + yield " * If this is not relevant to you, you may remove the following." + for e in extra_notes: + yield f" * {e}" + yield " */" + yield "" + yield from gen_monolithic_undef_all_core( + filt=k_specific, desc="MLD_CONFIG_PARAMETER_SET-specific files" + ) + yield "" + yield "#if !defined(MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS)" + yield from gen_monolithic_undef_all_core( + filt=lambda c: not native(c) + and k_generic(c) + and not fips202(c) + and "cbmc.h" not in c, + desc="MLD_CONFIG_PARAMETER_SET-generic files", + ) + # Handle cbmc.h manually -- most #define's therein are only defined when CBMC is set + # and need not be #undef'ed. In fact, #undef'ing them is risky since their names may + # well already be occupied. + yield "/* mldsa/src/cbmc.h */" + yield "#undef MLD_CBMC_H" + yield "#undef __contract__" + yield "#undef __loop__" + yield "" + yield "#if !defined(MLD_CONFIG_FIPS202_CUSTOM_HEADER)" + yield from gen_monolithic_undef_all_core( + filt=lambda c: not native(c) and k_generic(c) and fips202(c), + desc="FIPS-202 files", + ) + yield "#endif" + yield "" + yield "#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202)" + yield from gen_monolithic_undef_all_core(filt=native_fips202_core, desc="") + yield "#if defined(MLD_SYS_AARCH64)" + yield from gen_monolithic_undef_all_core( + filt=native_fips202_aarch64, desc="native code (FIPS202, AArch64)" + ) + yield "#endif" + yield "#if defined(MLD_SYS_X86_64)" + yield from gen_monolithic_undef_all_core( + filt=native_fips202_x86_64, desc="native code (FIPS202, x86_64)" + ) + yield "#endif" + yield "#endif" + yield "#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH)" + yield from gen_monolithic_undef_all_core(filt=native_arith_core, desc="") + yield "#if defined(MLD_SYS_AARCH64)" + yield from gen_monolithic_undef_all_core( + filt=native_arith_aarch64, desc="native code (Arith, AArch64)" + ) + yield "#endif" + yield "#if defined(MLD_SYS_X86_64)" + yield from gen_monolithic_undef_all_core( + filt=native_arith_x86_64, desc="native code (Arith, X86_64)" + ) + yield "#endif" + yield "#endif" + yield "#endif" + yield "" + + +def gen_monolithic_source_file(dry_run=False): + + def gen(): + c_sources = get_c_source_files(main_only=True, strip_mldsa=True) + yield from gen_header() + + yield "/******************************************************************************" + yield " *" + yield " * Single compilation unit (SCU) for fixed-level build of mldsa-native" + yield " *" + yield " * This compilation unit bundles together all source files for a build" + yield " * of mldsa-native for a fixed security level (MLDSA-44/65/87)." + yield " *" + yield " * # API" + yield " *" + yield " * The API exposed by this file is described in mldsa_native.h." + yield " *" + yield " * # Multi-level build" + yield " *" + yield " * If you want an SCU build of mldsa-native with support for multiple security" + yield " * levels, you need to include this file multiple times, and set" + yield " * MLD_CONFIG_MULTILEVEL_WITH_SHARED and MLD_CONFIG_MULTILEVEL_NO_SHARED" + yield " * appropriately. This is exemplified in examples/monolithic_build_multilevel" + yield " * and examples/monolithic_build_multilevel_native." + yield " *" + yield " * # Configuration" + yield " *" + yield " * The following options from the mldsa-native configuration are relevant:" + yield " *" + yield " * - MLD_CONFIG_FIPS202_CUSTOM_HEADER" + yield " * Set this option if you use a custom FIPS202 implementation." + yield " *" + yield " * - MLD_CONFIG_USE_NATIVE_BACKEND_ARITH" + yield " * Set this option if you want to include the native arithmetic backends" + yield " * in your build." + yield " *" + yield " * - MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202" + yield " * Set this option if you want to include the native FIPS202 backends" + yield " * in your build." + yield " *" + yield " * - MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS" + yield " * Set this option if you want to keep the directives defined in" + yield " * level-independent headers. This is needed for a multi-level build." + yield " */" + yield " " + yield " /* If parts of the mldsa-native source tree are not used," + yield " * consider reducing this header via `unifdef`." + yield " *" + yield " * Example:" + yield " * ```bash" + yield " * unifdef -UMLD_CONFIG_USE_NATIVE_BACKEND_ARITH mldsa_native.c" + yield " * ```" + yield " */" + yield "" + yield '#include "src/common.h"' + yield "" + for c in filter(lambda c: not native(c) and not fips202(c), c_sources): + yield f'#include "{c}"' + yield "" + yield "#if !defined(MLD_CONFIG_FIPS202_CUSTOM_HEADER)" + for c in filter(lambda c: not native(c) and fips202(c), c_sources): + yield f'#include "{c}"' + yield "#endif" + yield "" + yield "#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH)" + yield "#if defined(MLD_SYS_AARCH64)" + for c in filter(native_arith_aarch64, c_sources): + yield f'#include "{c}"' + yield "#endif" + yield "#if defined(MLD_SYS_X86_64)" + for c in filter(native_arith_x86_64, c_sources): + yield f'#include "{c}"' + yield "#endif" + yield "#endif" + yield "" + yield "#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202)" + yield "#if defined(MLD_SYS_AARCH64)" + for c in filter(native_fips202_aarch64, c_sources): + yield f'#include "{c}"' + yield "#endif" + yield "#if defined(MLD_SYS_X86_64)" + for c in filter(native_fips202_x86_64, c_sources): + yield f'#include "{c}"' + yield "#endif" + yield "#endif" + yield "" + yield from gen_macro_undefs() + + update_file( + "mldsa/mldsa_native.c", + "\n".join(gen()), + dry_run=dry_run, + ) + + def update_via_simpasm( infile_full, outdir, @@ -1895,6 +2255,8 @@ def _main(): high_level_status("Generated header guards") gen_preprocessor_comments(args.dry_run) high_level_status("Generated preprocessor comments") + gen_monolithic_source_file(args.dry_run) + high_level_status("Generated monolithic source files") synchronize_backends( dry_run=args.dry_run, From 03ccd5e6a0c476a80d105a61f63ad260d28322a7 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Sat, 1 Nov 2025 14:32:30 +0800 Subject: [PATCH 3/7] Examples: Add monolithic build (single level) example This commit adds a new example to mldsa-native ported from mlkem-native. It demonstrated how to build a single instance of mldsa-native in a single compilation unit. Signed-off-by: Matthias J. Kannwischer --- BIBLIOGRAPHY.md | 6 + examples/basic/expected_signatures.h | 6 +- examples/monolithic_build/.gitignore | 3 + examples/monolithic_build/Makefile | 139 ++++++ examples/monolithic_build/README.md | 17 + examples/monolithic_build/config_44.h | 434 ++++++++++++++++++ examples/monolithic_build/config_65.h | 434 ++++++++++++++++++ examples/monolithic_build/config_87.h | 434 ++++++++++++++++++ .../monolithic_build/expected_signatures.h | 1 + examples/monolithic_build/main.c | 134 ++++++ .../monolithic_build/mldsa/mldsa_native.c | 1 + .../monolithic_build/mldsa/mldsa_native.h | 1 + examples/monolithic_build/mldsa/src/cbmc.h | 1 + examples/monolithic_build/mldsa/src/common.h | 1 + examples/monolithic_build/mldsa/src/config.h | 1 + examples/monolithic_build/mldsa/src/ct.c | 1 + examples/monolithic_build/mldsa/src/ct.h | 1 + examples/monolithic_build/mldsa/src/debug.c | 1 + examples/monolithic_build/mldsa/src/debug.h | 1 + examples/monolithic_build/mldsa/src/fips202 | 1 + examples/monolithic_build/mldsa/src/ntt.c | 1 + examples/monolithic_build/mldsa/src/ntt.h | 1 + examples/monolithic_build/mldsa/src/packing.c | 1 + examples/monolithic_build/mldsa/src/packing.h | 1 + examples/monolithic_build/mldsa/src/params.h | 1 + examples/monolithic_build/mldsa/src/poly.c | 1 + examples/monolithic_build/mldsa/src/poly.h | 1 + examples/monolithic_build/mldsa/src/poly_kl.c | 1 + examples/monolithic_build/mldsa/src/poly_kl.h | 1 + examples/monolithic_build/mldsa/src/polyvec.c | 1 + examples/monolithic_build/mldsa/src/polyvec.h | 1 + examples/monolithic_build/mldsa/src/prehash.c | 1 + examples/monolithic_build/mldsa/src/prehash.h | 1 + .../monolithic_build/mldsa/src/randombytes.h | 1 + examples/monolithic_build/mldsa/src/reduce.h | 1 + .../monolithic_build/mldsa/src/rounding.h | 1 + examples/monolithic_build/mldsa/src/sign.c | 1 + examples/monolithic_build/mldsa/src/sign.h | 1 + .../monolithic_build/mldsa/src/symmetric.h | 1 + examples/monolithic_build/mldsa/src/sys.h | 1 + examples/monolithic_build/mldsa/src/zetas.inc | 1 + examples/monolithic_build/test_only_rng | 1 + scripts/tests | 24 +- 43 files changed, 1659 insertions(+), 5 deletions(-) create mode 100644 examples/monolithic_build/.gitignore create mode 100644 examples/monolithic_build/Makefile create mode 100644 examples/monolithic_build/README.md create mode 100644 examples/monolithic_build/config_44.h create mode 100644 examples/monolithic_build/config_65.h create mode 100644 examples/monolithic_build/config_87.h create mode 120000 examples/monolithic_build/expected_signatures.h create mode 100644 examples/monolithic_build/main.c create mode 120000 examples/monolithic_build/mldsa/mldsa_native.c create mode 120000 examples/monolithic_build/mldsa/mldsa_native.h create mode 120000 examples/monolithic_build/mldsa/src/cbmc.h create mode 120000 examples/monolithic_build/mldsa/src/common.h create mode 120000 examples/monolithic_build/mldsa/src/config.h create mode 120000 examples/monolithic_build/mldsa/src/ct.c create mode 120000 examples/monolithic_build/mldsa/src/ct.h create mode 120000 examples/monolithic_build/mldsa/src/debug.c create mode 120000 examples/monolithic_build/mldsa/src/debug.h create mode 120000 examples/monolithic_build/mldsa/src/fips202 create mode 120000 examples/monolithic_build/mldsa/src/ntt.c create mode 120000 examples/monolithic_build/mldsa/src/ntt.h create mode 120000 examples/monolithic_build/mldsa/src/packing.c create mode 120000 examples/monolithic_build/mldsa/src/packing.h create mode 120000 examples/monolithic_build/mldsa/src/params.h create mode 120000 examples/monolithic_build/mldsa/src/poly.c create mode 120000 examples/monolithic_build/mldsa/src/poly.h create mode 120000 examples/monolithic_build/mldsa/src/poly_kl.c create mode 120000 examples/monolithic_build/mldsa/src/poly_kl.h create mode 120000 examples/monolithic_build/mldsa/src/polyvec.c create mode 120000 examples/monolithic_build/mldsa/src/polyvec.h create mode 120000 examples/monolithic_build/mldsa/src/prehash.c create mode 120000 examples/monolithic_build/mldsa/src/prehash.h create mode 120000 examples/monolithic_build/mldsa/src/randombytes.h create mode 120000 examples/monolithic_build/mldsa/src/reduce.h create mode 120000 examples/monolithic_build/mldsa/src/rounding.h create mode 120000 examples/monolithic_build/mldsa/src/sign.c create mode 120000 examples/monolithic_build/mldsa/src/sign.h create mode 120000 examples/monolithic_build/mldsa/src/symmetric.h create mode 120000 examples/monolithic_build/mldsa/src/sys.h create mode 120000 examples/monolithic_build/mldsa/src/zetas.inc create mode 120000 examples/monolithic_build/test_only_rng diff --git a/BIBLIOGRAPHY.md b/BIBLIOGRAPHY.md index 3670e5545..ccedae055 100644 --- a/BIBLIOGRAPHY.md +++ b/BIBLIOGRAPHY.md @@ -14,6 +14,9 @@ source code and documentation. - National Institute of Standards and Technology * URL: https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements * Referenced from: + - [examples/monolithic_build/config_44.h](examples/monolithic_build/config_44.h) + - [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h) + - [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h) - [integration/liboqs/config_aarch64.h](integration/liboqs/config_aarch64.h) - [integration/liboqs/config_c.h](integration/liboqs/config_c.h) - [integration/liboqs/config_x86_64.h](integration/liboqs/config_x86_64.h) @@ -45,6 +48,9 @@ source code and documentation. * URL: https://csrc.nist.gov/pubs/fips/204/final * Referenced from: - [README.md](README.md) + - [examples/monolithic_build/config_44.h](examples/monolithic_build/config_44.h) + - [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h) + - [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h) - [mldsa/mldsa_native.h](mldsa/mldsa_native.h) - [mldsa/src/config.h](mldsa/src/config.h) - [mldsa/src/ct.h](mldsa/src/ct.h) diff --git a/examples/basic/expected_signatures.h b/examples/basic/expected_signatures.h index 9f3f9d658..bec610235 100644 --- a/examples/basic/expected_signatures.h +++ b/examples/basic/expected_signatures.h @@ -15,7 +15,7 @@ * The PCT modifies the PRNG state, so the KAT tests don't work. * We run KAT tests only for disabled PCT. */ #if !defined(MLD_CONFIG_KEYGEN_PCT) -#if MLD_CONFIG_PARAMETER_SET == 44 +#if MLD_CONFIG_API_PARAMETER_SET == 44 const uint8_t expected_signature[] = { 0x27, 0x5e, 0xbe, 0x2d, 0x23, 0x1a, 0x76, 0xc5, 0xd9, 0x77, 0xcb, 0x62, 0x25, 0x04, 0xdb, 0x23, 0x31, 0xa9, 0xa8, 0xcd, 0xbc, 0xde, 0xf2, 0x20, @@ -219,7 +219,7 @@ const uint8_t expected_signature[] = { 0x1f, 0x24, 0x38, 0x41, 0x45, 0x54, 0x5f, 0x69, 0x85, 0x8d, 0x93, 0x9e, 0xc5, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x25, 0x32, 0x42}; -#elif MLD_CONFIG_PARAMETER_SET == 65 +#elif MLD_CONFIG_API_PARAMETER_SET == 65 const uint8_t expected_signature[] = { 0x8b, 0x6f, 0x79, 0x00, 0xcc, 0x79, 0x57, 0xee, 0x16, 0x86, 0x87, 0xd5, 0xcf, 0xb6, 0x90, 0x2c, 0xc6, 0x30, 0xeb, 0x8d, 0x39, 0xae, 0x9b, 0xf1, @@ -497,7 +497,7 @@ const uint8_t expected_signature[] = { 0xdf, 0x0e, 0x1a, 0x20, 0x50, 0xf5, 0x02, 0x21, 0x30, 0x35, 0x3c, 0x60, 0x71, 0xad, 0xd0, 0xe3, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x17, 0x1d, 0x22, 0x2d}; -#elif MLD_CONFIG_PARAMETER_SET == 87 +#elif MLD_CONFIG_API_PARAMETER_SET == 87 const uint8_t expected_signature[] = { 0xdf, 0xe6, 0xe1, 0xa5, 0x20, 0xc1, 0xac, 0x98, 0x55, 0x2c, 0xf2, 0x13, 0x65, 0x42, 0xe2, 0xb0, 0x77, 0x5f, 0x15, 0x00, 0x8f, 0x14, 0x48, 0xa1, diff --git a/examples/monolithic_build/.gitignore b/examples/monolithic_build/.gitignore new file mode 100644 index 000000000..eb98a94f1 --- /dev/null +++ b/examples/monolithic_build/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +build diff --git a/examples/monolithic_build/Makefile b/examples/monolithic_build/Makefile new file mode 100644 index 000000000..52592c5dc --- /dev/null +++ b/examples/monolithic_build/Makefile @@ -0,0 +1,139 @@ +# Copyright (c) The mlkem-native project authors +# Copyright (c) The mldsa-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +.PHONY: build run clean +.DEFAULT_GOAL := all + +CC ?= gcc +AR ?= ar + +# Adjust CFLAGS if needed +CFLAGS := \ + -Wall \ + -Wextra \ + -Werror=unused-result \ + -Wpedantic \ + -Werror \ + -Wmissing-prototypes \ + -Wshadow \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wconversion \ + -Wsign-conversion \ + -Wno-long-long \ + -Wno-unknown-pragmas \ + -Wno-unused-command-line-argument \ + -O3 \ + -fomit-frame-pointer \ + -std=c99 \ + -pedantic \ + -MMD \ + $(CFLAGS) + +# The following only concerns the cross-compilation tests. +# You can likely ignore the following for your application. +# +# Append cross-prefix for cross compilation +# When called from the root Makefile, CROSS_PREFIX has already been added here +ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) +CC := $(CROSS_PREFIX)$(CC) +endif + +ifeq (,$(findstring $(CROSS_PREFIX),$(AR))) +AR := $(CROSS_PREFIX)$(AR) +endif + +Q ?= @ + +# Part A: +# +# mldsa-native source and header files +# +# Here, we use just a single monolithic compilation unit to include +# multiple instances of mldsa-native. + +MLD_SOURCE=mldsa/mldsa_native.c + +INC=-Imldsa/ -I./ + +# 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=$(RNG_SOURCE) main.c + +BUILD_DIR=build +BIN44=test_binary_mldsa44 +BIN65=test_binary_mldsa65 +BIN87=test_binary_mldsa87 +LIB44=libmldsa44.a +LIB65=libmldsa65.a +LIB87=libmldsa87.a + +BIN44_FULL=$(BUILD_DIR)/$(BIN44) +BIN65_FULL=$(BUILD_DIR)/$(BIN65) +BIN87_FULL=$(BUILD_DIR)/$(BIN87) + +LIB44_FULL=$(BUILD_DIR)/$(LIB44) +LIB65_FULL=$(BUILD_DIR)/$(LIB65) +LIB87_FULL=$(BUILD_DIR)/$(LIB87) + +$(LIB44_FULL): $(MLD_SOURCE) + $(Q)echo "$@" + $(Q)[ -d $(@) ] || mkdir -p $(@D) + $(Q)$(CC) -c $(CFLAGS) -DMLD_CONFIG_FILE="\"config_44.h\"" $(INC) $^ -o $(BUILD_DIR)/mldsa_native44.o + $(Q)$(AR) rcs $@ $(BUILD_DIR)/mldsa_native44.o + $(Q)strip -S $@ + +$(LIB65_FULL): $(MLD_SOURCE) + $(Q)echo "$@" + $(Q)[ -d $(@) ] || mkdir -p $(@D) + $(Q)$(CC) -c $(CFLAGS) -DMLD_CONFIG_FILE="\"config_65.h\"" $(INC) $^ -o $(BUILD_DIR)/mldsa_native65.o + $(Q)$(AR) rcs $@ $(BUILD_DIR)/mldsa_native65.o + $(Q)strip -S $@ + +$(LIB87_FULL): $(MLD_SOURCE) + $(Q)echo "$@" + $(Q)[ -d $(@) ] || mkdir -p $(@D) + $(Q)$(CC) -c $(CFLAGS) -DMLD_CONFIG_FILE="\"config_87.h\"" $(INC) $^ -o $(BUILD_DIR)/mldsa_native87.o + $(Q)$(AR) rcs $@ $(BUILD_DIR)/mldsa_native87.o + $(Q)strip -S $@ + +$(BIN44_FULL): $(APP_SOURCE) $(LIB44_FULL) + $(Q)echo "$@" + $(Q)[ -d $(@) ] || mkdir -p $(@D) + $(Q)$(CC) $(CFLAGS) -DMLD_CONFIG_API_PARAMETER_SET=44 $(INC) $^ -o $@ + +$(BIN65_FULL): $(APP_SOURCE) $(LIB65_FULL) + $(Q)echo "$@" + $(Q)[ -d $(@) ] || mkdir -p $(@D) + $(Q)$(CC) $(CFLAGS) -DMLD_CONFIG_API_PARAMETER_SET=65 $(INC) $^ -o $@ + +$(BIN87_FULL): $(APP_SOURCE) $(LIB87_FULL) + $(Q)echo "$@" + $(Q)[ -d $(@) ] || mkdir -p $(@D) + $(Q)$(CC) $(CFLAGS) -DMLD_CONFIG_API_PARAMETER_SET=87 $(INC) $^ -o $@ + +all: build + +build: $(BIN44_FULL) $(BIN65_FULL) $(BIN87_FULL) + +run: $(BIN44_FULL) $(BIN65_FULL) $(BIN87_FULL) + $(Q)$(EXEC_WRAPPER) ./$(BIN44_FULL) + $(Q)$(EXEC_WRAPPER) ./$(BIN65_FULL) + $(Q)$(EXEC_WRAPPER) ./$(BIN87_FULL) + +clean: + rm -rf $(BUILD_DIR) diff --git a/examples/monolithic_build/README.md b/examples/monolithic_build/README.md new file mode 100644 index 000000000..df8ceac2f --- /dev/null +++ b/examples/monolithic_build/README.md @@ -0,0 +1,17 @@ +[//]: # (SPDX-License-Identifier: CC-BY-4.0) + +# Single-level mldsa-native in a single compilation unit + +This directory contains a minimal example for how to build a single instance of mldsa-native in a single compilation +unit. Only the C-backend is exercised. + +The auto-generated source file [mldsa_native.c](mldsa/mldsa_native.c) includes all mldsa-native C source +files. Moreover, it clears all `#define`s clauses set by mldsa-native at the end, and is hence amenable to multiple +inclusion in another compilation unit. It exposes the API [../../mldsa/mldsa_native.h](mldsa/mldsa_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/config_44.h b/examples/monolithic_build/config_44.h new file mode 100644 index 000000000..2e69e5e9c --- /dev/null +++ b/examples/monolithic_build/config_44.h @@ -0,0 +1,434 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +/* References + * ========== + * + * - [FIPS140_3_IG] + * Implementation Guidance for FIPS 140-3 and the Cryptographic Module + * Validation Program National Institute of Standards and Technology + * https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements + * + * - [FIPS204] + * FIPS 204 Module-Lattice-Based Digital Signature Standard + * National Institute of Standards and Technology + * https://csrc.nist.gov/pubs/fips/204/final + */ + +#ifndef MLD_CONFIG_H +#define MLD_CONFIG_H + +/****************************************************************************** + * Name: MLD_CONFIG_PARAMETER_SET + * + * Description: Specifies the parameter set for ML-DSA + * - MLD_CONFIG_PARAMETER_SET=44 corresponds to ML-DSA-44 + * - MLD_CONFIG_PARAMETER_SET=65 corresponds to ML-DSA-65 + * - MLD_CONFIG_PARAMETER_SET=87 corresponds to ML-DSA-87 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_PARAMETER_SET 44 + +/****************************************************************************** + * Name: MLD_CONFIG_NAMESPACE_PREFIX + * + * Description: The prefix to use to namespace global symbols from mldsa/. + * + * In a multi-level build (that is, if either + * - MLD_CONFIG_MULTILEVEL_WITH_SHARED, or + * - MLD_CONFIG_MULTILEVEL_NO_SHARED, + * are set, level-dependent symbols will additionally be prefixed + * with the parameter set (44/65/87). + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_NAMESPACE_PREFIX mldsa + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_WITH_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, all MLD_CONFIG_PARAMETER_SET-independent + * code will be included in the build, including code needed only + * for other parameter sets. + * + * Example: TODO: add example + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_WITH_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_NO_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, no MLD_CONFIG_PARAMETER_SET-independent code + * will be included in the build. + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_NO_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of the default configuration file mldsa/config.h. + * + * When you need to build mldsa-native in multiple configurations, + * using varying MLD_CONFIG_FILE can be more convenient + * then configuring everything through CFLAGS. + * + * To use, MLD_CONFIG_FILE _must_ be defined prior + * to the inclusion of any mldsa-native headers. For example, + * it can be set by passing `-DMLD_CONFIG_FILE="..."` + * on the command line. + * + *****************************************************************************/ +/* #define MLD_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_ARITH_BACKEND_FILE + * + * Description: The arithmetic backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is unset, this option + * is ignored. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is set, this option must + * either be undefined or the filename of an arithmetic backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) && \ + !defined(MLD_CONFIG_ARITH_BACKEND_FILE) +#define MLD_CONFIG_ARITH_BACKEND_FILE "native/meta.h" +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_BACKEND_FILE + * + * Description: The FIPS-202 backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 is set, this option + * must either be undefined or the filename of a FIPS202 backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202) && \ + !defined(MLD_CONFIG_FIPS202_BACKEND_FILE) +#define MLD_CONFIG_FIPS202_BACKEND_FILE "fips202/native/auto.h" +#endif +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202X4_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202-X4 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202x4.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202X4_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_ZEROIZE + * + * Description: In compliance with @[FIPS204, Section 3.6.3], mldsa-native, + * zeroizes intermediate stack buffers before returning from + * function calls. + * + * Set this option and define `mld_zeroize_native` if you want to + * use a custom method to zeroize intermediate stack buffers. + * The default implementation uses SecureZeroMemory on Windows + * and a memset + compiler barrier otherwise. If neither of those + * is available on the target platform, compilation will fail, + * and you will need to use MLD_CONFIG_CUSTOM_ZEROIZE to provide + * a custom implementation of `mld_zeroize_native()`. + * + * WARNING: + * The explicit stack zeroization conducted by mldsa-native + * reduces the likelihood of data leaking on the stack, but + * does not eliminate it! The C standard makes no guarantee about + * where a compiler allocates structures and whether/where it makes + * copies of them. Also, in addition to entire structures, there + * may also be potentially exploitable leakage of individual values + * on the stack. + * + * If you need bullet-proof zeroization of the stack, you need to + * consider additional measures instead of what this feature + * provides. In this case, you can set mld_zeroize_native to a + * no-op. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_ZEROIZE + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_zeroize_native(void *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMCPY + * + * Description: Set this option and define `mld_memcpy` if you want to + * use a custom method to copy memory instead of the standard + * library memcpy function. + * + * The custom implementation must have the same signature and + * behavior as the standard memcpy function: + * void *mld_memcpy(void *dest, const void *src, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMCPY + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memcpy(void *dest, const void *src, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMSET + * + * Description: Set this option and define `mld_memset` if you want to + * use a custom method to set memory instead of the standard + * library memset function. + * + * The custom implementation must have the same signature and + * behavior as the standard memset function: + * void *mld_memset(void *s, int c, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMSET + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memset(void *s, int c, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_RANDOMBYTES + * + * Description: mldsa-native does not provide a secure randombytes + * implementation. Such an implementation has to provided by the + * consumer. + * + * If this option is not set, mldsa-native expects a function + * void randombytes(uint8_t *out, size_t outlen). + * + * Set this option and define `mld_randombytes` if you want to + * use a custom method to sample randombytes with a different name + * or signature. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_RANDOMBYTES + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_randombytes(uint8_t *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT + * + * Description: Compliance with @[FIPS140_3_IG, p.87] requires a + * Pairwise Consistency Test (PCT) to be carried out on a freshly + * generated keypair before it can be exported. + * + * Set this option if such a check should be implemented. + * In this case, crypto_sign_keypair_internal and + * crypto_sign_keypair will return a non-zero error code if the + * PCT failed. + * + * NOTE: This feature will drastically lower the performance of + * key generation. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT */ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + * + * Description: If this option is set, the user must provide a runtime + * function `static inline int mld_break_pct() { ... }` to + * indicate whether the PCT should be made fail. + * + * This option only has an effect if MLD_CONFIG_KEYGEN_PCT is set. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + #if !defined(__ASSEMBLER__) + #include "sys.h" + static MLD_INLINE int mld_break_pct(void) + { + ... return 0/1 depending on whether PCT should be broken ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_INTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of internal API. + * + * The primary use case for this option are single-CU builds, + * in which case this option can be set to `static`. + * + *****************************************************************************/ +#define MLD_CONFIG_INTERNAL_API_QUALIFIER static + +/****************************************************************************** + * Name: MLD_CONFIG_EXTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of mldsa-native's + * public API. + * + * The primary use case for this option are single-CU builds + * where the public API exposed by mldsa-native is wrapped by + * another API in the consuming application. In this case, + * even mldsa-native's public API can be marked `static`. + * + *****************************************************************************/ +/* #define MLD_CONFIG_EXTERNAL_API_QUALIFIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_CT_TESTING_ENABLED + * + * Description: If set, mldsa-native annotates data as secret / public using + * valgrind's annotations VALGRIND_MAKE_MEM_UNDEFINED and + * VALGRIND_MAKE_MEM_DEFINED, enabling various checks for secret- + * dependent control flow of variable time execution (depending + * on the exact version of valgrind installed). + * + *****************************************************************************/ +/* #define MLD_CONFIG_CT_TESTING_ENABLED */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly. + * + * By default, inline assembly is used to implement value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + * Inline assembly is also used to implement a secure zeroization + * function on non-Windows platforms. If this option is set and + * the target platform is not Windows, you MUST set + * MLD_CONFIG_CUSTOM_ZEROIZE and provide a custom zeroization + * function. + * + * If this option is set, MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 and + * and MLD_CONFIG_USE_NATIVE_BACKEND_ARITH will be ignored, and no + * native backends will be used. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM_VALUE_BARRIER + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly for value barriers. + * + * By default, inline assembly (if available) is used to implement + * value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM_VALUE_BARRIER */ + + + +/************************* Config internals ********************************/ + +/* Default namespace + * + * Don't change this. If you need a different namespace, re-define + * MLD_CONFIG_NAMESPACE_PREFIX above instead, and remove the following. + * + * The default MLDSA namespace is + * + * PQCP_MLDSA_NATIVE_MLDSA_ + * + * e.g., PQCP_MLDSA_NATIVE_MLDSA44_ + */ + +#if MLD_CONFIG_PARAMETER_SET == 44 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA44 +#elif MLD_CONFIG_PARAMETER_SET == 65 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA65 +#elif MLD_CONFIG_PARAMETER_SET == 87 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA87 +#endif + +#endif /* !MLD_CONFIG_H */ diff --git a/examples/monolithic_build/config_65.h b/examples/monolithic_build/config_65.h new file mode 100644 index 000000000..9a398fdc1 --- /dev/null +++ b/examples/monolithic_build/config_65.h @@ -0,0 +1,434 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +/* References + * ========== + * + * - [FIPS140_3_IG] + * Implementation Guidance for FIPS 140-3 and the Cryptographic Module + * Validation Program National Institute of Standards and Technology + * https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements + * + * - [FIPS204] + * FIPS 204 Module-Lattice-Based Digital Signature Standard + * National Institute of Standards and Technology + * https://csrc.nist.gov/pubs/fips/204/final + */ + +#ifndef MLD_CONFIG_H +#define MLD_CONFIG_H + +/****************************************************************************** + * Name: MLD_CONFIG_PARAMETER_SET + * + * Description: Specifies the parameter set for ML-DSA + * - MLD_CONFIG_PARAMETER_SET=44 corresponds to ML-DSA-44 + * - MLD_CONFIG_PARAMETER_SET=65 corresponds to ML-DSA-65 + * - MLD_CONFIG_PARAMETER_SET=87 corresponds to ML-DSA-87 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_PARAMETER_SET 65 + +/****************************************************************************** + * Name: MLD_CONFIG_NAMESPACE_PREFIX + * + * Description: The prefix to use to namespace global symbols from mldsa/. + * + * In a multi-level build (that is, if either + * - MLD_CONFIG_MULTILEVEL_WITH_SHARED, or + * - MLD_CONFIG_MULTILEVEL_NO_SHARED, + * are set, level-dependent symbols will additionally be prefixed + * with the parameter set (44/65/87). + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_NAMESPACE_PREFIX mldsa + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_WITH_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, all MLD_CONFIG_PARAMETER_SET-independent + * code will be included in the build, including code needed only + * for other parameter sets. + * + * Example: TODO: add example + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_WITH_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_NO_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, no MLD_CONFIG_PARAMETER_SET-independent code + * will be included in the build. + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_NO_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of the default configuration file mldsa/config.h. + * + * When you need to build mldsa-native in multiple configurations, + * using varying MLD_CONFIG_FILE can be more convenient + * then configuring everything through CFLAGS. + * + * To use, MLD_CONFIG_FILE _must_ be defined prior + * to the inclusion of any mldsa-native headers. For example, + * it can be set by passing `-DMLD_CONFIG_FILE="..."` + * on the command line. + * + *****************************************************************************/ +/* #define MLD_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_ARITH_BACKEND_FILE + * + * Description: The arithmetic backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is unset, this option + * is ignored. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is set, this option must + * either be undefined or the filename of an arithmetic backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) && \ + !defined(MLD_CONFIG_ARITH_BACKEND_FILE) +#define MLD_CONFIG_ARITH_BACKEND_FILE "native/meta.h" +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_BACKEND_FILE + * + * Description: The FIPS-202 backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 is set, this option + * must either be undefined or the filename of a FIPS202 backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202) && \ + !defined(MLD_CONFIG_FIPS202_BACKEND_FILE) +#define MLD_CONFIG_FIPS202_BACKEND_FILE "fips202/native/auto.h" +#endif +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202X4_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202-X4 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202x4.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202X4_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_ZEROIZE + * + * Description: In compliance with @[FIPS204, Section 3.6.3], mldsa-native, + * zeroizes intermediate stack buffers before returning from + * function calls. + * + * Set this option and define `mld_zeroize_native` if you want to + * use a custom method to zeroize intermediate stack buffers. + * The default implementation uses SecureZeroMemory on Windows + * and a memset + compiler barrier otherwise. If neither of those + * is available on the target platform, compilation will fail, + * and you will need to use MLD_CONFIG_CUSTOM_ZEROIZE to provide + * a custom implementation of `mld_zeroize_native()`. + * + * WARNING: + * The explicit stack zeroization conducted by mldsa-native + * reduces the likelihood of data leaking on the stack, but + * does not eliminate it! The C standard makes no guarantee about + * where a compiler allocates structures and whether/where it makes + * copies of them. Also, in addition to entire structures, there + * may also be potentially exploitable leakage of individual values + * on the stack. + * + * If you need bullet-proof zeroization of the stack, you need to + * consider additional measures instead of what this feature + * provides. In this case, you can set mld_zeroize_native to a + * no-op. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_ZEROIZE + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_zeroize_native(void *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMCPY + * + * Description: Set this option and define `mld_memcpy` if you want to + * use a custom method to copy memory instead of the standard + * library memcpy function. + * + * The custom implementation must have the same signature and + * behavior as the standard memcpy function: + * void *mld_memcpy(void *dest, const void *src, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMCPY + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memcpy(void *dest, const void *src, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMSET + * + * Description: Set this option and define `mld_memset` if you want to + * use a custom method to set memory instead of the standard + * library memset function. + * + * The custom implementation must have the same signature and + * behavior as the standard memset function: + * void *mld_memset(void *s, int c, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMSET + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memset(void *s, int c, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_RANDOMBYTES + * + * Description: mldsa-native does not provide a secure randombytes + * implementation. Such an implementation has to provided by the + * consumer. + * + * If this option is not set, mldsa-native expects a function + * void randombytes(uint8_t *out, size_t outlen). + * + * Set this option and define `mld_randombytes` if you want to + * use a custom method to sample randombytes with a different name + * or signature. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_RANDOMBYTES + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_randombytes(uint8_t *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT + * + * Description: Compliance with @[FIPS140_3_IG, p.87] requires a + * Pairwise Consistency Test (PCT) to be carried out on a freshly + * generated keypair before it can be exported. + * + * Set this option if such a check should be implemented. + * In this case, crypto_sign_keypair_internal and + * crypto_sign_keypair will return a non-zero error code if the + * PCT failed. + * + * NOTE: This feature will drastically lower the performance of + * key generation. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT */ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + * + * Description: If this option is set, the user must provide a runtime + * function `static inline int mld_break_pct() { ... }` to + * indicate whether the PCT should be made fail. + * + * This option only has an effect if MLD_CONFIG_KEYGEN_PCT is set. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + #if !defined(__ASSEMBLER__) + #include "sys.h" + static MLD_INLINE int mld_break_pct(void) + { + ... return 0/1 depending on whether PCT should be broken ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_INTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of internal API. + * + * The primary use case for this option are single-CU builds, + * in which case this option can be set to `static`. + * + *****************************************************************************/ +#define MLD_CONFIG_INTERNAL_API_QUALIFIER static + +/****************************************************************************** + * Name: MLD_CONFIG_EXTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of mldsa-native's + * public API. + * + * The primary use case for this option are single-CU builds + * where the public API exposed by mldsa-native is wrapped by + * another API in the consuming application. In this case, + * even mldsa-native's public API can be marked `static`. + * + *****************************************************************************/ +/* #define MLD_CONFIG_EXTERNAL_API_QUALIFIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_CT_TESTING_ENABLED + * + * Description: If set, mldsa-native annotates data as secret / public using + * valgrind's annotations VALGRIND_MAKE_MEM_UNDEFINED and + * VALGRIND_MAKE_MEM_DEFINED, enabling various checks for secret- + * dependent control flow of variable time execution (depending + * on the exact version of valgrind installed). + * + *****************************************************************************/ +/* #define MLD_CONFIG_CT_TESTING_ENABLED */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly. + * + * By default, inline assembly is used to implement value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + * Inline assembly is also used to implement a secure zeroization + * function on non-Windows platforms. If this option is set and + * the target platform is not Windows, you MUST set + * MLD_CONFIG_CUSTOM_ZEROIZE and provide a custom zeroization + * function. + * + * If this option is set, MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 and + * and MLD_CONFIG_USE_NATIVE_BACKEND_ARITH will be ignored, and no + * native backends will be used. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM_VALUE_BARRIER + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly for value barriers. + * + * By default, inline assembly (if available) is used to implement + * value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM_VALUE_BARRIER */ + + + +/************************* Config internals ********************************/ + +/* Default namespace + * + * Don't change this. If you need a different namespace, re-define + * MLD_CONFIG_NAMESPACE_PREFIX above instead, and remove the following. + * + * The default MLDSA namespace is + * + * PQCP_MLDSA_NATIVE_MLDSA_ + * + * e.g., PQCP_MLDSA_NATIVE_MLDSA44_ + */ + +#if MLD_CONFIG_PARAMETER_SET == 44 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA44 +#elif MLD_CONFIG_PARAMETER_SET == 65 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA65 +#elif MLD_CONFIG_PARAMETER_SET == 87 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA87 +#endif + +#endif /* !MLD_CONFIG_H */ diff --git a/examples/monolithic_build/config_87.h b/examples/monolithic_build/config_87.h new file mode 100644 index 000000000..bc4ab9172 --- /dev/null +++ b/examples/monolithic_build/config_87.h @@ -0,0 +1,434 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +/* References + * ========== + * + * - [FIPS140_3_IG] + * Implementation Guidance for FIPS 140-3 and the Cryptographic Module + * Validation Program National Institute of Standards and Technology + * https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements + * + * - [FIPS204] + * FIPS 204 Module-Lattice-Based Digital Signature Standard + * National Institute of Standards and Technology + * https://csrc.nist.gov/pubs/fips/204/final + */ + +#ifndef MLD_CONFIG_H +#define MLD_CONFIG_H + +/****************************************************************************** + * Name: MLD_CONFIG_PARAMETER_SET + * + * Description: Specifies the parameter set for ML-DSA + * - MLD_CONFIG_PARAMETER_SET=44 corresponds to ML-DSA-44 + * - MLD_CONFIG_PARAMETER_SET=65 corresponds to ML-DSA-65 + * - MLD_CONFIG_PARAMETER_SET=87 corresponds to ML-DSA-87 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_PARAMETER_SET 87 + +/****************************************************************************** + * Name: MLD_CONFIG_NAMESPACE_PREFIX + * + * Description: The prefix to use to namespace global symbols from mldsa/. + * + * In a multi-level build (that is, if either + * - MLD_CONFIG_MULTILEVEL_WITH_SHARED, or + * - MLD_CONFIG_MULTILEVEL_NO_SHARED, + * are set, level-dependent symbols will additionally be prefixed + * with the parameter set (44/65/87). + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_NAMESPACE_PREFIX mldsa + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_WITH_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, all MLD_CONFIG_PARAMETER_SET-independent + * code will be included in the build, including code needed only + * for other parameter sets. + * + * Example: TODO: add example + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_WITH_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_NO_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, no MLD_CONFIG_PARAMETER_SET-independent code + * will be included in the build. + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_NO_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of the default configuration file mldsa/config.h. + * + * When you need to build mldsa-native in multiple configurations, + * using varying MLD_CONFIG_FILE can be more convenient + * then configuring everything through CFLAGS. + * + * To use, MLD_CONFIG_FILE _must_ be defined prior + * to the inclusion of any mldsa-native headers. For example, + * it can be set by passing `-DMLD_CONFIG_FILE="..."` + * on the command line. + * + *****************************************************************************/ +/* #define MLD_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_ARITH_BACKEND_FILE + * + * Description: The arithmetic backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is unset, this option + * is ignored. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is set, this option must + * either be undefined or the filename of an arithmetic backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) && \ + !defined(MLD_CONFIG_ARITH_BACKEND_FILE) +#define MLD_CONFIG_ARITH_BACKEND_FILE "native/meta.h" +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_BACKEND_FILE + * + * Description: The FIPS-202 backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 is set, this option + * must either be undefined or the filename of a FIPS202 backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202) && \ + !defined(MLD_CONFIG_FIPS202_BACKEND_FILE) +#define MLD_CONFIG_FIPS202_BACKEND_FILE "fips202/native/auto.h" +#endif +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202X4_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202-X4 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202x4.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202X4_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_ZEROIZE + * + * Description: In compliance with @[FIPS204, Section 3.6.3], mldsa-native, + * zeroizes intermediate stack buffers before returning from + * function calls. + * + * Set this option and define `mld_zeroize_native` if you want to + * use a custom method to zeroize intermediate stack buffers. + * The default implementation uses SecureZeroMemory on Windows + * and a memset + compiler barrier otherwise. If neither of those + * is available on the target platform, compilation will fail, + * and you will need to use MLD_CONFIG_CUSTOM_ZEROIZE to provide + * a custom implementation of `mld_zeroize_native()`. + * + * WARNING: + * The explicit stack zeroization conducted by mldsa-native + * reduces the likelihood of data leaking on the stack, but + * does not eliminate it! The C standard makes no guarantee about + * where a compiler allocates structures and whether/where it makes + * copies of them. Also, in addition to entire structures, there + * may also be potentially exploitable leakage of individual values + * on the stack. + * + * If you need bullet-proof zeroization of the stack, you need to + * consider additional measures instead of what this feature + * provides. In this case, you can set mld_zeroize_native to a + * no-op. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_ZEROIZE + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_zeroize_native(void *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMCPY + * + * Description: Set this option and define `mld_memcpy` if you want to + * use a custom method to copy memory instead of the standard + * library memcpy function. + * + * The custom implementation must have the same signature and + * behavior as the standard memcpy function: + * void *mld_memcpy(void *dest, const void *src, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMCPY + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memcpy(void *dest, const void *src, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMSET + * + * Description: Set this option and define `mld_memset` if you want to + * use a custom method to set memory instead of the standard + * library memset function. + * + * The custom implementation must have the same signature and + * behavior as the standard memset function: + * void *mld_memset(void *s, int c, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMSET + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memset(void *s, int c, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_RANDOMBYTES + * + * Description: mldsa-native does not provide a secure randombytes + * implementation. Such an implementation has to provided by the + * consumer. + * + * If this option is not set, mldsa-native expects a function + * void randombytes(uint8_t *out, size_t outlen). + * + * Set this option and define `mld_randombytes` if you want to + * use a custom method to sample randombytes with a different name + * or signature. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_RANDOMBYTES + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_randombytes(uint8_t *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT + * + * Description: Compliance with @[FIPS140_3_IG, p.87] requires a + * Pairwise Consistency Test (PCT) to be carried out on a freshly + * generated keypair before it can be exported. + * + * Set this option if such a check should be implemented. + * In this case, crypto_sign_keypair_internal and + * crypto_sign_keypair will return a non-zero error code if the + * PCT failed. + * + * NOTE: This feature will drastically lower the performance of + * key generation. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT */ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + * + * Description: If this option is set, the user must provide a runtime + * function `static inline int mld_break_pct() { ... }` to + * indicate whether the PCT should be made fail. + * + * This option only has an effect if MLD_CONFIG_KEYGEN_PCT is set. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + #if !defined(__ASSEMBLER__) + #include "sys.h" + static MLD_INLINE int mld_break_pct(void) + { + ... return 0/1 depending on whether PCT should be broken ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_INTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of internal API. + * + * The primary use case for this option are single-CU builds, + * in which case this option can be set to `static`. + * + *****************************************************************************/ +#define MLD_CONFIG_INTERNAL_API_QUALIFIER static + +/****************************************************************************** + * Name: MLD_CONFIG_EXTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of mldsa-native's + * public API. + * + * The primary use case for this option are single-CU builds + * where the public API exposed by mldsa-native is wrapped by + * another API in the consuming application. In this case, + * even mldsa-native's public API can be marked `static`. + * + *****************************************************************************/ +/* #define MLD_CONFIG_EXTERNAL_API_QUALIFIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_CT_TESTING_ENABLED + * + * Description: If set, mldsa-native annotates data as secret / public using + * valgrind's annotations VALGRIND_MAKE_MEM_UNDEFINED and + * VALGRIND_MAKE_MEM_DEFINED, enabling various checks for secret- + * dependent control flow of variable time execution (depending + * on the exact version of valgrind installed). + * + *****************************************************************************/ +/* #define MLD_CONFIG_CT_TESTING_ENABLED */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly. + * + * By default, inline assembly is used to implement value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + * Inline assembly is also used to implement a secure zeroization + * function on non-Windows platforms. If this option is set and + * the target platform is not Windows, you MUST set + * MLD_CONFIG_CUSTOM_ZEROIZE and provide a custom zeroization + * function. + * + * If this option is set, MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 and + * and MLD_CONFIG_USE_NATIVE_BACKEND_ARITH will be ignored, and no + * native backends will be used. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM_VALUE_BARRIER + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly for value barriers. + * + * By default, inline assembly (if available) is used to implement + * value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM_VALUE_BARRIER */ + + + +/************************* Config internals ********************************/ + +/* Default namespace + * + * Don't change this. If you need a different namespace, re-define + * MLD_CONFIG_NAMESPACE_PREFIX above instead, and remove the following. + * + * The default MLDSA namespace is + * + * PQCP_MLDSA_NATIVE_MLDSA_ + * + * e.g., PQCP_MLDSA_NATIVE_MLDSA44_ + */ + +#if MLD_CONFIG_PARAMETER_SET == 44 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA44 +#elif MLD_CONFIG_PARAMETER_SET == 65 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA65 +#elif MLD_CONFIG_PARAMETER_SET == 87 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA87 +#endif + +#endif /* !MLD_CONFIG_H */ diff --git a/examples/monolithic_build/expected_signatures.h b/examples/monolithic_build/expected_signatures.h new file mode 120000 index 000000000..694d65628 --- /dev/null +++ b/examples/monolithic_build/expected_signatures.h @@ -0,0 +1 @@ +../basic/expected_signatures.h \ No newline at end of file diff --git a/examples/monolithic_build/main.c b/examples/monolithic_build/main.c new file mode 100644 index 000000000..164526583 --- /dev/null +++ b/examples/monolithic_build/main.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) The mlkem-native project authors + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#include +#include +#include + +/* Import public mldsa-native API + * + * This requires specifying the parameter set and namespace prefix + * used for the build. + * + * The parameter set is configured on the command line + */ + +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa +#include +#include "expected_signatures.h" +#include "test_only_rng/notrandombytes.h" + +#define CHECK(x) \ + do \ + { \ + int rc; \ + rc = (x); \ + if (!rc) \ + { \ + fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \ + return 1; \ + } \ + } while (0) + +int main(void) +{ + const char *test_msg = + "This is a test message for ML-DSA digital signature algorithm!"; + const char *test_ctx = "test_context_123"; + size_t msglen = strlen(test_msg); + size_t ctxlen = strlen(test_ctx); + + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + uint8_t sig[CRYPTO_BYTES]; + uint8_t sm[msglen + CRYPTO_BYTES]; /* signed message buffer */ + uint8_t m2[msglen]; /* recovered message buffer */ + size_t siglen; + size_t smlen; + size_t mlen; + + /* WARNING: Test-only + * Normally, you would want to seed a PRNG with trustworthy entropy here. */ + randombytes_reset(); + + printf("ML-DSA-%d monolithic_build Example\n", MLD_CONFIG_API_PARAMETER_SET); + printf("======================\n\n"); + + printf("Message: %s\n", test_msg); + printf("Context: %s\n\n", test_ctx); + + printf("Generating keypair ... "); + + /* Alice generates a public/private key pair */ + CHECK(crypto_sign_keypair(pk, sk) == 0); + + printf("DONE\n"); + printf("Signing message... "); + + /* Alice signs the message */ + CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Verifying signature... "); + + /* Bob verifies Alice's signature */ + CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, pk) == 0); + + printf("DONE\n"); + printf("Creating signed message... "); + + /* Alternative API: Create a signed message (signature + message combined) */ + CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Opening signed message... "); + + /* Bob opens the signed message to recover the original message */ + CHECK(crypto_sign_open(m2, &mlen, sm, smlen, (const uint8_t *)test_ctx, + ctxlen, pk) == 0); + + printf("DONE\n"); + printf("Compare messages... "); + + /* Verify the recovered message matches the original */ + CHECK(mlen == msglen); + CHECK(memcmp(test_msg, m2, msglen) == 0); + + printf("DONE\n\n"); + + printf("Results:\n"); + printf("--------\n"); + printf("Public key size: %d bytes\n", CRYPTO_PUBLICKEYBYTES); + printf("Secret key size: %d bytes\n", CRYPTO_SECRETKEYBYTES); + printf("Signature size: %d bytes\n", CRYPTO_BYTES); + printf("Message length: %zu bytes\n", msglen); + printf("Signature length: %zu bytes\n", siglen); + printf("Signed msg length: %zu bytes\n", smlen); + +#if !defined(MLD_CONFIG_KEYGEN_PCT) + /* Check against expected signature to make sure that + * we integrated the library correctly */ + printf("Checking deterministic signature... "); + { + /* Compare the generated signature directly against the expected signature + */ + CHECK(siglen == sizeof(expected_signature)); + CHECK(memcmp(sig, expected_signature, siglen) == 0); + } + printf("DONE\n"); +#else + printf( + "[WARNING] Skipping KAT test since PCT is enabled and modifies PRNG\n"); +#endif + + printf("Signature verification completed successfully!\n"); + + printf("\nAll tests passed! ML-DSA signature verification successful.\n"); + return 0; +} diff --git a/examples/monolithic_build/mldsa/mldsa_native.c b/examples/monolithic_build/mldsa/mldsa_native.c new file mode 120000 index 000000000..107fe39e1 --- /dev/null +++ b/examples/monolithic_build/mldsa/mldsa_native.c @@ -0,0 +1 @@ +../../../mldsa/mldsa_native.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/mldsa_native.h b/examples/monolithic_build/mldsa/mldsa_native.h new file mode 120000 index 000000000..f25191336 --- /dev/null +++ b/examples/monolithic_build/mldsa/mldsa_native.h @@ -0,0 +1 @@ +../../../mldsa/mldsa_native.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/cbmc.h b/examples/monolithic_build/mldsa/src/cbmc.h new file mode 120000 index 000000000..9fd253c4c --- /dev/null +++ b/examples/monolithic_build/mldsa/src/cbmc.h @@ -0,0 +1 @@ +../../../../mldsa/src/cbmc.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/common.h b/examples/monolithic_build/mldsa/src/common.h new file mode 120000 index 000000000..7baea8129 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/common.h @@ -0,0 +1 @@ +../../../../mldsa/src/common.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/config.h b/examples/monolithic_build/mldsa/src/config.h new file mode 120000 index 000000000..e8185dc91 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/config.h @@ -0,0 +1 @@ +../../../../mldsa/src/config.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/ct.c b/examples/monolithic_build/mldsa/src/ct.c new file mode 120000 index 000000000..3f32692cc --- /dev/null +++ b/examples/monolithic_build/mldsa/src/ct.c @@ -0,0 +1 @@ +../../../../mldsa/src/ct.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/ct.h b/examples/monolithic_build/mldsa/src/ct.h new file mode 120000 index 000000000..d46bb57d3 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/ct.h @@ -0,0 +1 @@ +../../../../mldsa/src/ct.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/debug.c b/examples/monolithic_build/mldsa/src/debug.c new file mode 120000 index 000000000..e4b0d5d00 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/debug.c @@ -0,0 +1 @@ +../../../../mldsa/src/debug.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/debug.h b/examples/monolithic_build/mldsa/src/debug.h new file mode 120000 index 000000000..92949bb27 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/debug.h @@ -0,0 +1 @@ +../../../../mldsa/src/debug.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/fips202 b/examples/monolithic_build/mldsa/src/fips202 new file mode 120000 index 000000000..829380ed0 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/fips202 @@ -0,0 +1 @@ +../../../../mldsa/src/fips202 \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/ntt.c b/examples/monolithic_build/mldsa/src/ntt.c new file mode 120000 index 000000000..a8ab8e18c --- /dev/null +++ b/examples/monolithic_build/mldsa/src/ntt.c @@ -0,0 +1 @@ +../../../../mldsa/src/ntt.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/ntt.h b/examples/monolithic_build/mldsa/src/ntt.h new file mode 120000 index 000000000..6cf19a6b3 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/ntt.h @@ -0,0 +1 @@ +../../../../mldsa/src/ntt.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/packing.c b/examples/monolithic_build/mldsa/src/packing.c new file mode 120000 index 000000000..0da6e8062 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/packing.c @@ -0,0 +1 @@ +../../../../mldsa/src/packing.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/packing.h b/examples/monolithic_build/mldsa/src/packing.h new file mode 120000 index 000000000..3dc7c9dae --- /dev/null +++ b/examples/monolithic_build/mldsa/src/packing.h @@ -0,0 +1 @@ +../../../../mldsa/src/packing.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/params.h b/examples/monolithic_build/mldsa/src/params.h new file mode 120000 index 000000000..0a530a256 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/params.h @@ -0,0 +1 @@ +../../../../mldsa/src/params.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/poly.c b/examples/monolithic_build/mldsa/src/poly.c new file mode 120000 index 000000000..2a793df40 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/poly.c @@ -0,0 +1 @@ +../../../../mldsa/src/poly.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/poly.h b/examples/monolithic_build/mldsa/src/poly.h new file mode 120000 index 000000000..0cdab9983 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/poly.h @@ -0,0 +1 @@ +../../../../mldsa/src/poly.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/poly_kl.c b/examples/monolithic_build/mldsa/src/poly_kl.c new file mode 120000 index 000000000..8a27154af --- /dev/null +++ b/examples/monolithic_build/mldsa/src/poly_kl.c @@ -0,0 +1 @@ +../../../../mldsa/src/poly_kl.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/poly_kl.h b/examples/monolithic_build/mldsa/src/poly_kl.h new file mode 120000 index 000000000..f981ad481 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/poly_kl.h @@ -0,0 +1 @@ +../../../../mldsa/src/poly_kl.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/polyvec.c b/examples/monolithic_build/mldsa/src/polyvec.c new file mode 120000 index 000000000..33e86a831 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/polyvec.c @@ -0,0 +1 @@ +../../../../mldsa/src/polyvec.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/polyvec.h b/examples/monolithic_build/mldsa/src/polyvec.h new file mode 120000 index 000000000..417aa2e0c --- /dev/null +++ b/examples/monolithic_build/mldsa/src/polyvec.h @@ -0,0 +1 @@ +../../../../mldsa/src/polyvec.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/prehash.c b/examples/monolithic_build/mldsa/src/prehash.c new file mode 120000 index 000000000..b47ab34db --- /dev/null +++ b/examples/monolithic_build/mldsa/src/prehash.c @@ -0,0 +1 @@ +../../../../mldsa/src/prehash.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/prehash.h b/examples/monolithic_build/mldsa/src/prehash.h new file mode 120000 index 000000000..c7dec4db1 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/prehash.h @@ -0,0 +1 @@ +../../../../mldsa/src/prehash.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/randombytes.h b/examples/monolithic_build/mldsa/src/randombytes.h new file mode 120000 index 000000000..d372260e5 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/randombytes.h @@ -0,0 +1 @@ +../../../../mldsa/src/randombytes.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/reduce.h b/examples/monolithic_build/mldsa/src/reduce.h new file mode 120000 index 000000000..e1405ac0a --- /dev/null +++ b/examples/monolithic_build/mldsa/src/reduce.h @@ -0,0 +1 @@ +../../../../mldsa/src/reduce.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/rounding.h b/examples/monolithic_build/mldsa/src/rounding.h new file mode 120000 index 000000000..c58bd9fae --- /dev/null +++ b/examples/monolithic_build/mldsa/src/rounding.h @@ -0,0 +1 @@ +../../../../mldsa/src/rounding.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/sign.c b/examples/monolithic_build/mldsa/src/sign.c new file mode 120000 index 000000000..fad774fba --- /dev/null +++ b/examples/monolithic_build/mldsa/src/sign.c @@ -0,0 +1 @@ +../../../../mldsa/src/sign.c \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/sign.h b/examples/monolithic_build/mldsa/src/sign.h new file mode 120000 index 000000000..2ba1e2a0e --- /dev/null +++ b/examples/monolithic_build/mldsa/src/sign.h @@ -0,0 +1 @@ +../../../../mldsa/src/sign.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/symmetric.h b/examples/monolithic_build/mldsa/src/symmetric.h new file mode 120000 index 000000000..eb4af39ca --- /dev/null +++ b/examples/monolithic_build/mldsa/src/symmetric.h @@ -0,0 +1 @@ +../../../../mldsa/src/symmetric.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/sys.h b/examples/monolithic_build/mldsa/src/sys.h new file mode 120000 index 000000000..7322c1c94 --- /dev/null +++ b/examples/monolithic_build/mldsa/src/sys.h @@ -0,0 +1 @@ +../../../../mldsa/src/sys.h \ No newline at end of file diff --git a/examples/monolithic_build/mldsa/src/zetas.inc b/examples/monolithic_build/mldsa/src/zetas.inc new file mode 120000 index 000000000..b9361143a --- /dev/null +++ b/examples/monolithic_build/mldsa/src/zetas.inc @@ -0,0 +1 @@ +../../../../mldsa/src/zetas.inc \ No newline at end of file diff --git a/examples/monolithic_build/test_only_rng b/examples/monolithic_build/test_only_rng new file mode 120000 index 000000000..b1e04d9b8 --- /dev/null +++ b/examples/monolithic_build/test_only_rng @@ -0,0 +1 @@ +../basic/test_only_rng/ \ No newline at end of file diff --git a/scripts/tests b/scripts/tests index 9405a259a..a7be6612c 100755 --- a/scripts/tests +++ b/scripts/tests @@ -202,6 +202,8 @@ class TEST_TYPES(Enum): SIZE = 7 BASIC = 8 BRING_YOUR_OWN_FIPS202 = 9 + MONOLITHIC_BUILD = 10 + MONOLITHIC_BUILD_MULTILEVEL = 11 def is_benchmark(self): return self in [TEST_TYPES.BENCH, TEST_TYPES.BENCH_COMPONENTS] @@ -211,7 +213,12 @@ class TEST_TYPES(Enum): @staticmethod def examples(): - return [TEST_TYPES.BASIC, TEST_TYPES.BRING_YOUR_OWN_FIPS202] + return [ + TEST_TYPES.BASIC, + TEST_TYPES.BRING_YOUR_OWN_FIPS202, + TEST_TYPES.MONOLITHIC_BUILD, + TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL, + ] @staticmethod def from_string(s): @@ -244,12 +251,20 @@ class TEST_TYPES(Enum): return "Example (mldsa-native as code package)" if self == TEST_TYPES.BRING_YOUR_OWN_FIPS202: return "Example (bring your own FIPS-202 implementation)" + if self == TEST_TYPES.MONOLITHIC_BUILD: + return "Example (single compilation unit)" + if self == TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL: + return "Example (single compilation unit, multilevel)" def make_dir(self): if self == TEST_TYPES.BASIC: return "examples/basic" if self == TEST_TYPES.BRING_YOUR_OWN_FIPS202: return "examples/bring_your_own_fips202" + if self == TEST_TYPES.MONOLITHIC_BUILD: + return "examples/monolithic_build" + if self == TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL: + return "examples/monolithic_build_multilevel" return "" def make_target(self): @@ -953,7 +968,12 @@ def cli(): examples_parser.add_argument( "-l", help="Explicitly list the examples to run; can be called multiple times", - choices=["basic", "bring_your_own_fips202"], + choices=[ + "basic", + "bring_your_own_fips202", + "monolithic_build", + "monolithic_build_multilevel", + ], action="append", ) From 26afc1cc3331bce660e13e5f69f5c54f6acdc70a Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Sat, 1 Nov 2025 15:18:56 +0800 Subject: [PATCH 4/7] Examples: Add monolithic_build_multilevel example This ports the monolithic_build_multilevel from mlkem-native. This examples demonstrated how to build multiple instances of mldsa-native in a single compilation unit Signed-off-by: Matthias J. Kannwischer --- BIBLIOGRAPHY.md | 2 + .../monolithic_build_multilevel/.gitignore | 4 + examples/monolithic_build_multilevel/Makefile | 103 ++ .../monolithic_build_multilevel/README.md | 87 ++ .../expected_signatures.h | 886 ++++++++++++++++++ examples/monolithic_build_multilevel/main.c | 348 +++++++ .../mldsa/mldsa_native.c | 1 + .../mldsa/mldsa_native.h | 1 + .../mldsa/src/cbmc.h | 1 + .../mldsa/src/common.h | 1 + .../mldsa/src/config.h | 1 + .../mldsa/src/ct.c | 1 + .../mldsa/src/ct.h | 1 + .../mldsa/src/debug.c | 1 + .../mldsa/src/debug.h | 1 + .../mldsa/src/fips202 | 1 + .../mldsa/src/ntt.c | 1 + .../mldsa/src/ntt.h | 1 + .../mldsa/src/packing.c | 1 + .../mldsa/src/packing.h | 1 + .../mldsa/src/params.h | 1 + .../mldsa/src/poly.c | 1 + .../mldsa/src/poly.h | 1 + .../mldsa/src/poly_kl.c | 1 + .../mldsa/src/poly_kl.h | 1 + .../mldsa/src/polyvec.c | 1 + .../mldsa/src/polyvec.h | 1 + .../mldsa/src/prehash.c | 1 + .../mldsa/src/prehash.h | 1 + .../mldsa/src/randombytes.h | 1 + .../mldsa/src/reduce.h | 1 + .../mldsa/src/rounding.h | 1 + .../mldsa/src/sign.c | 1 + .../mldsa/src/sign.h | 1 + .../mldsa/src/symmetric.h | 1 + .../mldsa/src/sys.h | 1 + .../mldsa/src/zetas.inc | 1 + .../mldsa_native_all.c | 30 + .../mldsa_native_all.h | 37 + .../multilevel_config.h | 437 +++++++++ .../monolithic_build_multilevel/test_only_rng | 1 + 41 files changed, 1966 insertions(+) create mode 100644 examples/monolithic_build_multilevel/.gitignore create mode 100644 examples/monolithic_build_multilevel/Makefile create mode 100644 examples/monolithic_build_multilevel/README.md create mode 100644 examples/monolithic_build_multilevel/expected_signatures.h create mode 100644 examples/monolithic_build_multilevel/main.c create mode 120000 examples/monolithic_build_multilevel/mldsa/mldsa_native.c create mode 120000 examples/monolithic_build_multilevel/mldsa/mldsa_native.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/cbmc.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/common.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/config.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/ct.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/ct.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/debug.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/debug.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/fips202 create mode 120000 examples/monolithic_build_multilevel/mldsa/src/ntt.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/ntt.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/packing.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/packing.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/params.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/poly.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/poly.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/poly_kl.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/poly_kl.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/polyvec.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/polyvec.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/prehash.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/prehash.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/randombytes.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/reduce.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/rounding.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/sign.c create mode 120000 examples/monolithic_build_multilevel/mldsa/src/sign.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/symmetric.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/sys.h create mode 120000 examples/monolithic_build_multilevel/mldsa/src/zetas.inc create mode 100644 examples/monolithic_build_multilevel/mldsa_native_all.c create mode 100644 examples/monolithic_build_multilevel/mldsa_native_all.h create mode 100644 examples/monolithic_build_multilevel/multilevel_config.h create mode 120000 examples/monolithic_build_multilevel/test_only_rng diff --git a/BIBLIOGRAPHY.md b/BIBLIOGRAPHY.md index ccedae055..86c16884a 100644 --- a/BIBLIOGRAPHY.md +++ b/BIBLIOGRAPHY.md @@ -17,6 +17,7 @@ source code and documentation. - [examples/monolithic_build/config_44.h](examples/monolithic_build/config_44.h) - [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h) - [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h) + - [examples/monolithic_build_multilevel/multilevel_config.h](examples/monolithic_build_multilevel/multilevel_config.h) - [integration/liboqs/config_aarch64.h](integration/liboqs/config_aarch64.h) - [integration/liboqs/config_c.h](integration/liboqs/config_c.h) - [integration/liboqs/config_x86_64.h](integration/liboqs/config_x86_64.h) @@ -51,6 +52,7 @@ source code and documentation. - [examples/monolithic_build/config_44.h](examples/monolithic_build/config_44.h) - [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h) - [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h) + - [examples/monolithic_build_multilevel/multilevel_config.h](examples/monolithic_build_multilevel/multilevel_config.h) - [mldsa/mldsa_native.h](mldsa/mldsa_native.h) - [mldsa/src/config.h](mldsa/src/config.h) - [mldsa/src/ct.h](mldsa/src/ct.h) diff --git a/examples/monolithic_build_multilevel/.gitignore b/examples/monolithic_build_multilevel/.gitignore new file mode 100644 index 000000000..834e99720 --- /dev/null +++ b/examples/monolithic_build_multilevel/.gitignore @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +build/ +*.d diff --git a/examples/monolithic_build_multilevel/Makefile b/examples/monolithic_build_multilevel/Makefile new file mode 100644 index 000000000..dd238cd72 --- /dev/null +++ b/examples/monolithic_build_multilevel/Makefile @@ -0,0 +1,103 @@ +# Copyright (c) The mlkem-native project authors +# Copyright (c) The mldsa-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +.PHONY: build run clean +.DEFAULT_GOAL := all + +CC ?= gcc +AR ?= ar + +# Adjust CFLAGS if needed +CFLAGS := \ + -Wall \ + -Wextra \ + -Werror=unused-result \ + -Wpedantic \ + -Werror \ + -Wmissing-prototypes \ + -Wshadow \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wconversion \ + -Wsign-conversion \ + -Wno-long-long \ + -Wno-unknown-pragmas \ + -Wno-unused-command-line-argument \ + -O3 \ + -fomit-frame-pointer \ + -std=c99 \ + -pedantic \ + -MMD \ + $(CFLAGS) + + +# The following only concerns the cross-compilation tests. +# You can likely ignore the following for your application. +# +# Append cross-prefix for cross compilation +# When called from the root Makefile, CROSS_PREFIX has already been added here +ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) +CC := $(CROSS_PREFIX)$(CC) +endif + +ifeq (,$(findstring $(CROSS_PREFIX),$(AR))) +AR := $(CROSS_PREFIX)$(AR) +endif + +# Part A: +# +# mldsa-native source and header files +# +# Here, we use just a single monolithic compilation unit to include +# multiple instances of mldsa-native. + +MLD_SOURCE=mldsa_native_all.c + +INC=-Imldsa/ -I./ + +# 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=$(RNG_SOURCE) main.c + +BUILD_DIR=build +BIN=test_binary +LIB=libmldsa.a + +BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN) +LIB_NAME_FULL=$(BUILD_DIR)/$(LIB) + +$(LIB_NAME_FULL): $(MLD_SOURCE) + echo "$@" + mkdir -p $(BUILD_DIR) + $(CC) -c $(CFLAGS) $(INC) $^ -o $(BUILD_DIR)/mldsa_native.o + $(AR) rcs $@ $(BUILD_DIR)/mldsa_native.o + strip -S $@ + +$(BINARY_NAME_FULL): $(APP_SOURCE) $(LIB_NAME_FULL) + echo "$@" + mkdir -p $(BUILD_DIR) + $(CC) $(CFLAGS) $(INC) $^ -o $@ + +all: build + +build: $(BINARY_NAME_FULL) + +run: $(BINARY_NAME_FULL) + $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL) + +clean: + rm -rf $(BUILD_DIR) diff --git a/examples/monolithic_build_multilevel/README.md b/examples/monolithic_build_multilevel/README.md new file mode 100644 index 000000000..2e9cb7a78 --- /dev/null +++ b/examples/monolithic_build_multilevel/README.md @@ -0,0 +1,87 @@ +[//]: # (SPDX-License-Identifier: CC-BY-4.0) + +# Multi-level mldsa-native in a single compilation unit + +This directory contains a minimal example for how to build multiple instances of mldsa-native in a single compilation +unit. Only the C-backend is exercised. + +The auto-generated source file [mldsa_native.c](mldsa/mldsa_native.c) includes all mldsa-native C source +files. Moreover, it clears all `#define`s clauses set by mldsa-native at the end, and is hence amenable to multiple +inclusion in another compilation unit. + +The manually written source file [mldsa_native_all.c](mldsa_native_all.c) includes +[mldsa_native.c](mldsa/mldsa_native.c) three times, each time using the fixed config +[multilevel_config.h](multilevel_config.h), but changing the security level (specified +by `MLD_CONFIG_PARAMETER_SET`) every time. +```C +#define MLD_CONFIG_FILE "multilevel_config.h" + +/* Three instances of mldsa-native for all security levels */ + +/* Include level-independent code */ +#define MLD_CONFIG_MULTILEVEL_WITH_SHARED +/* Keep level-independent headers at the end of monobuild file */ +#define MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS +#define MLD_CONFIG_PARAMETER_SET 44 +#include "mldsa_native.c" +#undef MLD_CONFIG_PARAMETER_SET +#undef MLD_CONFIG_MULTILEVEL_WITH_SHARED + +/* Exclude level-independent code */ +#define MLD_CONFIG_MULTILEVEL_NO_SHARED +#define MLD_CONFIG_PARAMETER_SET 65 +#include "mldsa_native.c" +#undef MLD_CONFIG_PARAMETER_SET +/* `#undef` all headers at the and of the monobuild file */ +#undef MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS + +#define MLD_CONFIG_PARAMETER_SET 87 +#include "mldsa_native.c" +#undef MLD_CONFIG_PARAMETER_SET +``` + +Note the setting `MLD_CONFIG_MULTILEVEL_WITH_SHARED` which forces the inclusion of all level-independent +code in the MLDSA-44 build, and the setting `MLD_CONFIG_MULTILEVEL_NO_SHARED`, which drops all +level-independent code in the subsequent builds. Finally, `MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS` entails that +`mldsa_native.c` does not `#undefine` the `#define` clauses from level-independent files. + +To make the monolithic multi-level build accessible from the application source [main.c](main.c), we provide +[mldsa_native_all.h](mldsa_native_all.h), which includes [mldsa_native.h](../../mldsa/mldsa_native.h) once per +configuration. Note that we don't refer to the configuration using `MLD_CONFIG_FILE`, but by setting +`MLD_CONFIG_API_XXX` explicitly. Otherwise, [mldsa_native.h](../../mldsa/mldsa_native.h) would include the confg, which +would lead to name-clashes upon multiple use. + +```C +#define MLD_CONFIG_API_NO_SUPERCOP + +/* API for MLDSA-44 */ +#define MLD_CONFIG_API_PARAMETER_SET 44 +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa44 +#include +#undef MLD_CONFIG_API_PARAMETER_SET +#undef MLD_CONFIG_API_NAMESPACE_PREFIX +#undef MLD_H + +/* API for MLDSA-65*/ +#define MLD_CONFIG_API_PARAMETER_SET 65 +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa65 +#include +#undef MLD_CONFIG_API_PARAMETER_SET +#undef MLD_CONFIG_API_NAMESPACE_PREFIX +#undef MLD_H + +/* API for MLDSA_87 */ +#define MLD_CONFIG_API_PARAMETER_SET 87 +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa87 +#include +#undef MLD_CONFIG_API_PARAMETER_SET +#undef MLD_CONFIG_API_NAMESPACE_PREFIX +#undef MLD_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_multilevel/expected_signatures.h b/examples/monolithic_build_multilevel/expected_signatures.h new file mode 100644 index 000000000..77433c322 --- /dev/null +++ b/examples/monolithic_build_multilevel/expected_signatures.h @@ -0,0 +1,886 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#ifndef EXPECTED_SIGNATURES_H +#define EXPECTED_SIGNATURES_H + +#include + +/* Expected deterministic signatures for each parameter set + * These are generated using the same test message, context, and deterministic + * RNG as used in the basic example. + * + * The PCT modifies the PRNG state, so the KAT tests don't work. + * We run KAT tests only for disabled PCT. */ +#if !defined(MLD_CONFIG_KEYGEN_PCT) +const uint8_t expected_signature_44[] = { + 0x27, 0x5e, 0xbe, 0x2d, 0x23, 0x1a, 0x76, 0xc5, 0xd9, 0x77, 0xcb, 0x62, + 0x25, 0x04, 0xdb, 0x23, 0x31, 0xa9, 0xa8, 0xcd, 0xbc, 0xde, 0xf2, 0x20, + 0xfd, 0xa7, 0xb5, 0xf5, 0x59, 0xae, 0xe6, 0xdd, 0x62, 0xfa, 0x34, 0x96, + 0x4f, 0x1d, 0xcd, 0x84, 0x82, 0xee, 0xc1, 0x74, 0x96, 0x3d, 0x98, 0xd9, + 0x42, 0x9d, 0xd0, 0x77, 0x9c, 0xf9, 0x9e, 0x0e, 0xa7, 0xcb, 0x70, 0xeb, + 0xe7, 0xcd, 0xce, 0x8c, 0xdc, 0x37, 0x15, 0x95, 0x0e, 0x24, 0x70, 0x4f, + 0x33, 0x6e, 0x4f, 0xad, 0xed, 0x4d, 0xf3, 0xe5, 0x38, 0xc1, 0xcd, 0xbb, + 0xde, 0xf1, 0xd2, 0x0d, 0xd6, 0x6b, 0xa3, 0x68, 0x92, 0x4c, 0x4b, 0x4f, + 0x89, 0xa0, 0xa8, 0xc8, 0x36, 0x93, 0x91, 0x17, 0xe7, 0x16, 0xed, 0xcb, + 0xdc, 0xf6, 0x28, 0x13, 0x32, 0x60, 0x14, 0xe0, 0x28, 0x7a, 0x69, 0x05, + 0x1d, 0xf7, 0x3b, 0xdf, 0x18, 0x0c, 0xaf, 0xba, 0x46, 0xf1, 0x5e, 0xd4, + 0xd3, 0xd0, 0x8e, 0x9a, 0xe2, 0xac, 0xdd, 0x0e, 0x5f, 0xb1, 0x69, 0xe2, + 0x74, 0x77, 0x2e, 0x52, 0xf9, 0x11, 0x3d, 0xd8, 0xe5, 0x36, 0x6f, 0x7d, + 0x7d, 0xde, 0x7c, 0xa7, 0x1d, 0x37, 0xdf, 0x6d, 0x5e, 0xea, 0xc8, 0xc0, + 0x72, 0x3f, 0x79, 0xbd, 0x0b, 0x6d, 0x7f, 0x9a, 0x15, 0x90, 0xda, 0xc1, + 0xae, 0xce, 0xf3, 0x44, 0x35, 0x5e, 0x83, 0x86, 0x7e, 0x89, 0x18, 0xa7, + 0x97, 0x8e, 0x87, 0x7c, 0x15, 0xd2, 0xd2, 0x7e, 0xf2, 0xc8, 0x29, 0x4f, + 0x70, 0x0f, 0xa6, 0xd4, 0x76, 0xe8, 0xdd, 0x7d, 0x7a, 0x2d, 0xfe, 0x0a, + 0x0c, 0x5c, 0xb1, 0xef, 0xec, 0x1a, 0x32, 0xca, 0x87, 0xff, 0x6b, 0xb1, + 0xa0, 0xe1, 0x2e, 0x01, 0x52, 0xb2, 0xb8, 0x74, 0x34, 0xb3, 0xfb, 0x15, + 0x0f, 0x17, 0xca, 0x74, 0xc1, 0xc1, 0x61, 0x86, 0x40, 0x38, 0x58, 0xba, + 0x82, 0x26, 0x66, 0x33, 0xa4, 0x52, 0xf3, 0xb5, 0x36, 0x60, 0xd8, 0x5a, + 0x8d, 0x9d, 0x28, 0x18, 0x3a, 0x68, 0x34, 0x2a, 0xa2, 0xe2, 0xb5, 0x39, + 0xed, 0x7d, 0xe5, 0xbe, 0x46, 0xb9, 0x04, 0x0c, 0xf3, 0xef, 0x88, 0x6e, + 0x9d, 0x6f, 0x23, 0xe2, 0x44, 0xe5, 0x2e, 0x3a, 0x7a, 0x1d, 0x49, 0x0f, + 0xdd, 0xcd, 0xd6, 0x4e, 0x0d, 0x0b, 0xc3, 0x35, 0xf2, 0xd1, 0x5d, 0x73, + 0x5d, 0x07, 0xca, 0x5c, 0xbd, 0x14, 0xec, 0x57, 0xb3, 0xbd, 0x37, 0xe7, + 0xdf, 0x06, 0x7d, 0xe0, 0x58, 0x4a, 0xcf, 0x7a, 0xc5, 0xa7, 0x24, 0x62, + 0x6f, 0x09, 0x75, 0x69, 0x74, 0x7f, 0xdf, 0xc8, 0x69, 0x5c, 0x20, 0x10, + 0x3a, 0xe8, 0x01, 0x12, 0xa3, 0xfb, 0xda, 0x4c, 0x3a, 0x0d, 0x3c, 0x3e, + 0x26, 0xe0, 0xa6, 0x7f, 0xb2, 0x6b, 0x0b, 0x68, 0x0a, 0x68, 0x86, 0xb1, + 0xfa, 0x61, 0x3a, 0xe8, 0x77, 0xdc, 0x42, 0xf7, 0xf4, 0x39, 0x9a, 0x40, + 0x58, 0x71, 0xc7, 0x0f, 0xf4, 0x0e, 0xc5, 0x1e, 0xe0, 0x28, 0x45, 0x7d, + 0xba, 0x84, 0xe4, 0x34, 0x69, 0xf9, 0xa5, 0x8a, 0x80, 0x43, 0xc0, 0x8d, + 0x04, 0x33, 0x43, 0xb8, 0xd7, 0x5d, 0x93, 0xed, 0x0f, 0x31, 0x6a, 0x4d, + 0xbf, 0xb7, 0x44, 0x41, 0x1b, 0xd4, 0xac, 0x9d, 0x83, 0x66, 0x08, 0x92, + 0xad, 0x3c, 0x0e, 0x1a, 0xe8, 0xd4, 0xe1, 0x5c, 0x63, 0xcf, 0x27, 0x48, + 0x5a, 0x8f, 0xc5, 0x6f, 0x83, 0x6b, 0x6f, 0xe8, 0xda, 0x1f, 0xba, 0xe9, + 0x7e, 0x11, 0xab, 0x8b, 0x4e, 0xc1, 0x9e, 0x23, 0x69, 0x1f, 0x42, 0x40, + 0xad, 0xbb, 0xfb, 0x4f, 0xe2, 0x50, 0xc9, 0x46, 0xe7, 0x15, 0x15, 0xf8, + 0x61, 0x09, 0x2a, 0x0b, 0x37, 0x43, 0xd4, 0x98, 0x5f, 0xc8, 0x4d, 0x06, + 0xe7, 0x0c, 0x3f, 0x83, 0x59, 0xd5, 0xcd, 0x2d, 0xde, 0x1e, 0x3a, 0x87, + 0x4e, 0xf7, 0x0a, 0x3c, 0x84, 0x72, 0x47, 0x11, 0x02, 0x6c, 0xe8, 0x93, + 0xcd, 0x24, 0xe9, 0x23, 0x86, 0x78, 0x53, 0xe0, 0xc6, 0x2f, 0xba, 0xa7, + 0xed, 0xaf, 0xba, 0x42, 0x80, 0x0d, 0xe6, 0xae, 0xda, 0xed, 0xbc, 0x65, + 0x21, 0x6d, 0x13, 0x90, 0x61, 0xb4, 0x05, 0x7b, 0x07, 0x86, 0xd7, 0x89, + 0x30, 0x9c, 0xc1, 0x9a, 0x41, 0x4d, 0xe8, 0x2b, 0x35, 0x21, 0x3a, 0x8a, + 0x60, 0x83, 0x1a, 0x97, 0x10, 0x98, 0xb6, 0xe1, 0x6b, 0xb5, 0xb1, 0xa1, + 0x36, 0x34, 0x60, 0x1b, 0x96, 0x5d, 0x1f, 0x2a, 0xd8, 0xf2, 0x94, 0xdd, + 0x58, 0x3d, 0x0f, 0xbe, 0x9d, 0xfc, 0xf5, 0x24, 0xb1, 0xd2, 0xc3, 0x36, + 0xef, 0xdb, 0x8e, 0x97, 0x3c, 0x9a, 0x4f, 0x48, 0xe3, 0x84, 0x91, 0xd8, + 0x39, 0x91, 0xf6, 0x55, 0xeb, 0x62, 0x51, 0x3d, 0x8f, 0x55, 0x60, 0x5e, + 0x00, 0xe0, 0xd2, 0xc7, 0x66, 0x51, 0xf1, 0xe2, 0xb7, 0x43, 0xc3, 0xe6, + 0x12, 0x9a, 0xe5, 0x84, 0xe0, 0x10, 0x76, 0xc7, 0x75, 0x6e, 0xa6, 0xee, + 0x11, 0xe4, 0xaf, 0xbd, 0x8a, 0x4f, 0x1d, 0x05, 0x29, 0x4f, 0xce, 0xa5, + 0x73, 0x92, 0x57, 0x7e, 0x0d, 0x11, 0xbc, 0xf8, 0x74, 0x4d, 0xf7, 0xb9, + 0x40, 0x0d, 0x5a, 0xa1, 0x19, 0x76, 0x4a, 0xae, 0x21, 0x16, 0xd4, 0x3f, + 0x76, 0xbf, 0x27, 0xbd, 0x2f, 0xe4, 0x25, 0x21, 0x00, 0x4e, 0xcc, 0x7c, + 0xc6, 0x57, 0xa4, 0xbf, 0xf1, 0x56, 0x90, 0xe0, 0xa4, 0xa3, 0xee, 0xcf, + 0x43, 0x4f, 0xda, 0x77, 0x47, 0x51, 0x79, 0x6a, 0x29, 0xb4, 0x2c, 0xdf, + 0xca, 0x47, 0xcb, 0xb8, 0x82, 0x7e, 0x44, 0x62, 0x9b, 0x8f, 0x61, 0x7b, + 0x3a, 0x93, 0x82, 0x1f, 0x69, 0xb7, 0xb1, 0xa6, 0x2c, 0xe1, 0xb2, 0x65, + 0xa0, 0x6d, 0x6f, 0xe4, 0x79, 0xd8, 0x30, 0xe0, 0xee, 0xd8, 0x83, 0x01, + 0xb2, 0x1f, 0x5c, 0x90, 0x44, 0x86, 0x48, 0x11, 0xf9, 0x11, 0xff, 0xea, + 0x45, 0x43, 0xae, 0x8a, 0x6b, 0x99, 0xf2, 0x1f, 0x02, 0x51, 0x4a, 0x35, + 0x02, 0x34, 0xd3, 0xe8, 0xda, 0xb1, 0x4b, 0xe3, 0xa5, 0x60, 0xce, 0x67, + 0xe3, 0x62, 0x59, 0xfc, 0x00, 0x0a, 0xe2, 0xfe, 0x7b, 0x1e, 0xe6, 0xf5, + 0x75, 0x19, 0x9b, 0x5e, 0xcb, 0xe6, 0xf5, 0x80, 0x9e, 0x3c, 0xb8, 0x54, + 0xd6, 0x0b, 0xfd, 0x48, 0xe0, 0xfa, 0x82, 0x2b, 0x5b, 0x26, 0xf9, 0x49, + 0xaf, 0xbe, 0x9c, 0x78, 0x73, 0xce, 0xc5, 0x65, 0xe2, 0x94, 0x2b, 0xd9, + 0xd0, 0x27, 0x3a, 0x66, 0x3e, 0xe2, 0xe0, 0x10, 0x79, 0x3d, 0xde, 0xc8, + 0x47, 0xdb, 0x1e, 0xc3, 0xe7, 0x51, 0xae, 0x59, 0xeb, 0x38, 0x66, 0x63, + 0x40, 0x8f, 0xbe, 0x1e, 0xb2, 0x2b, 0xeb, 0x64, 0x5f, 0xdd, 0x24, 0xc4, + 0x5a, 0x25, 0x59, 0xa2, 0xda, 0x4f, 0xdf, 0xf8, 0xb0, 0xb0, 0xf7, 0xcd, + 0x1f, 0x14, 0xcd, 0x09, 0x48, 0x70, 0x27, 0x1b, 0xde, 0xc4, 0xf0, 0xf3, + 0x56, 0x97, 0x8a, 0xb7, 0xf4, 0x19, 0x76, 0xe3, 0x9a, 0x33, 0x55, 0xfe, + 0x93, 0x68, 0xca, 0x1f, 0x3d, 0x44, 0x86, 0x39, 0x5d, 0x84, 0x58, 0x50, + 0xf2, 0xf1, 0xea, 0x4a, 0x5c, 0x1c, 0x74, 0xf0, 0x4b, 0xa5, 0x9c, 0x30, + 0xa0, 0x14, 0x1a, 0x80, 0xe0, 0xde, 0x3e, 0xae, 0x7f, 0x10, 0x18, 0x4a, + 0x1e, 0x9e, 0x6b, 0x75, 0x1a, 0xca, 0x08, 0x4e, 0x61, 0x72, 0x43, 0x9b, + 0x18, 0x4d, 0x2c, 0xd8, 0xb4, 0xc9, 0xea, 0x00, 0xb0, 0xdf, 0x1b, 0xcb, + 0x03, 0xc3, 0x7a, 0x27, 0xff, 0x41, 0x9d, 0xf9, 0xfd, 0xb3, 0x0c, 0xc0, + 0x48, 0x5d, 0x7c, 0xae, 0x5a, 0x72, 0x69, 0x93, 0x68, 0xe1, 0x9e, 0x9f, + 0x1f, 0x5c, 0x0a, 0x60, 0x90, 0x1a, 0x8e, 0x5a, 0x30, 0xd4, 0x2c, 0xbd, + 0xe1, 0x20, 0x51, 0xbc, 0x1c, 0x50, 0xb5, 0xf7, 0x42, 0x23, 0x35, 0x0f, + 0x92, 0xe2, 0xbb, 0x2a, 0x04, 0xa7, 0xde, 0x2e, 0x25, 0xfa, 0xed, 0x20, + 0x83, 0x9c, 0xd4, 0x56, 0xe0, 0x4d, 0x8d, 0x79, 0xa5, 0xa0, 0x6f, 0x49, + 0x62, 0x82, 0x9a, 0xa7, 0x4e, 0x54, 0x95, 0x0a, 0xc6, 0x5e, 0x27, 0x65, + 0x6d, 0x11, 0x2b, 0x35, 0x72, 0x34, 0x48, 0xd2, 0xe4, 0x9e, 0x07, 0x7d, + 0x03, 0x27, 0x15, 0x93, 0x55, 0x5c, 0x32, 0x43, 0xdb, 0x34, 0x8d, 0xbd, + 0x8d, 0x88, 0xa5, 0x24, 0x07, 0x93, 0x89, 0x37, 0xb9, 0x17, 0x15, 0xad, + 0xc7, 0x68, 0x86, 0x63, 0x0f, 0x10, 0x53, 0x8f, 0x40, 0xd3, 0x7b, 0x22, + 0x2b, 0x1a, 0x4c, 0xcb, 0x4f, 0x51, 0xf1, 0x3b, 0x19, 0xb8, 0x42, 0x53, + 0xaf, 0xf6, 0xb9, 0x57, 0x7f, 0xba, 0x8d, 0xb8, 0xb7, 0x3b, 0xe3, 0xc5, + 0xab, 0x4a, 0x26, 0x21, 0x6e, 0xce, 0x27, 0xb8, 0xc3, 0x99, 0x56, 0x14, + 0xdd, 0x5b, 0x61, 0x82, 0xbf, 0xd3, 0xc8, 0x76, 0xee, 0x22, 0xaf, 0x21, + 0x21, 0x1d, 0x4e, 0x33, 0xb5, 0x43, 0x3a, 0xfb, 0x91, 0xa0, 0xaa, 0xe3, + 0x10, 0x4a, 0x50, 0x42, 0xd4, 0x5f, 0x92, 0x0e, 0x71, 0x60, 0x4f, 0xaa, + 0xef, 0x66, 0x45, 0xfe, 0xf7, 0xc8, 0xb0, 0x73, 0x75, 0x91, 0x0b, 0x86, + 0x40, 0xa5, 0x02, 0x28, 0xf7, 0xe0, 0x1f, 0x5d, 0xe6, 0xe3, 0xa4, 0x57, + 0xbd, 0x29, 0xaa, 0x53, 0xae, 0x35, 0x30, 0x78, 0x73, 0xd6, 0xb7, 0x01, + 0x9d, 0x13, 0x50, 0xf6, 0x39, 0xa2, 0x3e, 0x03, 0x04, 0xaa, 0x6d, 0xcf, + 0x6b, 0xff, 0x9a, 0xbe, 0x3e, 0x0a, 0xd4, 0x20, 0xce, 0x42, 0x1f, 0xca, + 0x2f, 0xd3, 0x2c, 0xd1, 0xf4, 0xd2, 0x50, 0xd3, 0xa2, 0xc1, 0x1e, 0x87, + 0xbf, 0xeb, 0xb8, 0xa8, 0xd4, 0x1c, 0x96, 0xb8, 0x8e, 0xbe, 0x35, 0x5f, + 0x08, 0x28, 0x20, 0x2b, 0xdc, 0xa4, 0xf5, 0xf6, 0xde, 0xca, 0x1e, 0xcb, + 0x93, 0x3b, 0x64, 0x79, 0x00, 0x3c, 0x8d, 0xbb, 0x5c, 0x7a, 0x40, 0x14, + 0x58, 0x12, 0xa4, 0xf7, 0x6e, 0x51, 0xfb, 0xe7, 0x6f, 0x49, 0x5b, 0xc2, + 0xc9, 0x05, 0x38, 0x9c, 0x08, 0x78, 0x71, 0x27, 0x2b, 0xf5, 0xbf, 0xd6, + 0x38, 0xaa, 0x45, 0xe1, 0xe1, 0x4c, 0xfb, 0xfd, 0xb7, 0xe6, 0xcf, 0xad, + 0x9e, 0x56, 0xaf, 0x12, 0x12, 0x98, 0xe6, 0x38, 0xaa, 0xee, 0xdb, 0x9e, + 0xca, 0xe1, 0x79, 0x6d, 0x44, 0xfb, 0x19, 0x50, 0x92, 0x00, 0x06, 0x2c, + 0x24, 0x71, 0x6c, 0x34, 0x45, 0xac, 0xf9, 0x82, 0x66, 0xa8, 0x63, 0x80, + 0xa8, 0x5b, 0x21, 0x3c, 0x36, 0x71, 0x93, 0x40, 0x7b, 0xff, 0xa2, 0xd0, + 0x72, 0xb4, 0x66, 0xfa, 0xfc, 0xa0, 0xee, 0xca, 0x15, 0x73, 0x52, 0xe7, + 0x9d, 0x11, 0xd3, 0xbc, 0xab, 0x37, 0x31, 0x0e, 0xaf, 0xdc, 0x05, 0x30, + 0x79, 0x8c, 0x25, 0x75, 0x5c, 0x60, 0xc7, 0x9a, 0xfc, 0x88, 0xea, 0xe6, + 0x09, 0x9f, 0xd1, 0x4f, 0x13, 0xf4, 0x41, 0x54, 0x5b, 0x7a, 0xe4, 0x49, + 0x3c, 0x0f, 0x15, 0xe9, 0xa4, 0x85, 0xb2, 0x92, 0x07, 0xea, 0xea, 0x7c, + 0xc1, 0x6d, 0xa9, 0x03, 0xb3, 0x31, 0xce, 0x1e, 0x82, 0xca, 0x9e, 0x3c, + 0x88, 0x88, 0xc1, 0x04, 0x5f, 0xbe, 0xd5, 0x94, 0x0d, 0x67, 0x98, 0x27, + 0xd0, 0x0f, 0x43, 0xf3, 0xb3, 0xfc, 0xff, 0x24, 0xa2, 0x1e, 0x17, 0x06, + 0xb0, 0x52, 0x16, 0x7c, 0xd8, 0x49, 0x74, 0x51, 0xcf, 0x2d, 0x36, 0x16, + 0xb0, 0x88, 0xb2, 0x2b, 0x1d, 0x72, 0x70, 0xab, 0xe2, 0xf6, 0x5f, 0xa5, + 0x2d, 0x4e, 0xd1, 0x42, 0x3c, 0x83, 0x84, 0xb2, 0x56, 0xeb, 0x8d, 0xce, + 0x33, 0x46, 0xdb, 0x3d, 0x4f, 0x97, 0xea, 0x37, 0x5e, 0x0d, 0xd7, 0x4c, + 0x9a, 0x7e, 0xc9, 0x0e, 0x69, 0x4d, 0x97, 0x15, 0x1e, 0x09, 0xbe, 0x7e, + 0xff, 0xe8, 0xf5, 0xab, 0xe9, 0xe7, 0xed, 0x4b, 0x41, 0xa5, 0xf2, 0x2a, + 0x24, 0x48, 0x8b, 0x72, 0x4b, 0x9d, 0xcf, 0x45, 0xdb, 0xc0, 0xaf, 0xa8, + 0x0f, 0x0f, 0x67, 0x37, 0xd3, 0x8b, 0xe1, 0x67, 0x90, 0xd8, 0x1c, 0x58, + 0x36, 0x46, 0x51, 0x52, 0xea, 0xb4, 0x75, 0xb1, 0xcd, 0xc5, 0x39, 0x16, + 0xe0, 0xec, 0x16, 0xf7, 0xf8, 0x0f, 0x5d, 0x13, 0x84, 0x62, 0x34, 0x86, + 0x42, 0x05, 0xa8, 0x08, 0x84, 0xa9, 0x77, 0x12, 0xc1, 0x56, 0xdd, 0x28, + 0xde, 0x39, 0x33, 0x21, 0x3d, 0xbd, 0x94, 0xce, 0xe4, 0xb3, 0x17, 0x9b, + 0x09, 0x20, 0xf0, 0x25, 0xce, 0x00, 0x34, 0x8e, 0x12, 0x94, 0x74, 0x0b, + 0x16, 0xa1, 0x60, 0x76, 0x24, 0xf0, 0xbf, 0xe3, 0x3a, 0x83, 0x8f, 0x40, + 0x47, 0x2e, 0x1c, 0xd5, 0x35, 0x25, 0x87, 0xb3, 0x11, 0xdc, 0x98, 0xb0, + 0xa6, 0x5f, 0x6a, 0x05, 0x1d, 0x06, 0x8d, 0xe8, 0xb0, 0x98, 0xf0, 0x43, + 0x29, 0x84, 0xe4, 0xef, 0x34, 0x67, 0x74, 0x64, 0xe8, 0xb8, 0xf0, 0xd4, + 0x9e, 0xc1, 0x3f, 0x5f, 0xeb, 0xe0, 0x9b, 0x37, 0xf8, 0x75, 0x46, 0x47, + 0xa5, 0x3e, 0x42, 0x20, 0x50, 0xc4, 0x5d, 0xf3, 0xdf, 0x4e, 0xf8, 0x0e, + 0x1e, 0x15, 0x10, 0x3e, 0xf1, 0x68, 0xad, 0x87, 0xad, 0xe5, 0x45, 0x5e, + 0x22, 0xba, 0x2e, 0x51, 0xa0, 0xbf, 0xdc, 0x87, 0xca, 0xe4, 0x1f, 0x2f, + 0x2c, 0xae, 0xa9, 0x14, 0xd7, 0xdd, 0x01, 0xa8, 0x4f, 0x43, 0xcb, 0x84, + 0x92, 0xbf, 0xf9, 0x3d, 0xf0, 0x6b, 0x19, 0x43, 0xb0, 0xdf, 0xff, 0x94, + 0x76, 0xe2, 0x84, 0xf9, 0x31, 0x88, 0x7e, 0xc6, 0x87, 0x58, 0xbe, 0x5d, + 0x8b, 0xf8, 0xb5, 0xdc, 0x95, 0x16, 0x5f, 0xa1, 0x2c, 0xe8, 0x53, 0x36, + 0x64, 0xf5, 0x5d, 0xa0, 0x74, 0x12, 0x78, 0x59, 0x73, 0x69, 0x5a, 0x2b, + 0x36, 0x4a, 0xff, 0x5b, 0xef, 0x49, 0x2c, 0xb2, 0x9e, 0x59, 0xf0, 0x39, + 0x56, 0xe1, 0xd0, 0x1a, 0x05, 0xb2, 0x7c, 0xd1, 0x40, 0x09, 0xdf, 0x00, + 0xc9, 0x15, 0x53, 0xa2, 0xda, 0x84, 0xb5, 0x85, 0x05, 0x76, 0xa6, 0x1b, + 0xcb, 0x06, 0xb2, 0xc8, 0xa0, 0xc5, 0x23, 0x8f, 0xb0, 0xe8, 0xf5, 0xd9, + 0xd0, 0x19, 0x29, 0xfe, 0x2d, 0x9a, 0x57, 0x76, 0x5f, 0xf2, 0xef, 0x71, + 0x16, 0xee, 0x28, 0x7b, 0xe4, 0x48, 0xeb, 0xda, 0xe0, 0xd5, 0xbc, 0x0e, + 0x46, 0x6b, 0x06, 0x5d, 0xe5, 0x91, 0x2d, 0xcb, 0xc4, 0x53, 0xa6, 0x16, + 0xd5, 0xe7, 0xd8, 0xf1, 0xdd, 0x4f, 0xbb, 0xcc, 0x55, 0x67, 0x19, 0x98, + 0x94, 0x95, 0x5e, 0xd6, 0xf5, 0xf7, 0xe8, 0x6a, 0xf7, 0x20, 0x86, 0x3a, + 0x43, 0xbf, 0xe9, 0xec, 0x6b, 0x33, 0x49, 0x19, 0x43, 0xfb, 0xeb, 0x3f, + 0xf4, 0x9d, 0x29, 0x66, 0xb9, 0x6e, 0xb5, 0x15, 0x4b, 0x8d, 0x3c, 0x3c, + 0xfa, 0xf2, 0x87, 0xba, 0x61, 0x11, 0x40, 0xe6, 0xb4, 0x6f, 0xf5, 0xe1, + 0x24, 0x32, 0x69, 0x3e, 0xff, 0xf7, 0xbc, 0xee, 0x82, 0xf2, 0x9e, 0x6d, + 0x3f, 0x6c, 0xcc, 0x0f, 0x4f, 0xc3, 0xf1, 0xdb, 0x1e, 0x81, 0xd7, 0x9b, + 0x22, 0xa8, 0xa7, 0x36, 0x6d, 0xa9, 0x6f, 0x46, 0x1a, 0xa7, 0xff, 0x00, + 0x4b, 0xd8, 0xab, 0xe7, 0x50, 0x3b, 0xe9, 0xc0, 0x57, 0xec, 0x8d, 0x0c, + 0xa0, 0xee, 0x8c, 0x2a, 0x74, 0xf2, 0x94, 0xf9, 0x0c, 0x20, 0x14, 0xd9, + 0xad, 0x0d, 0x4e, 0xac, 0x35, 0x44, 0x59, 0x28, 0x24, 0x31, 0x32, 0xaa, + 0x6d, 0xc2, 0x13, 0xb9, 0xee, 0x75, 0x0c, 0x5f, 0x39, 0xef, 0x31, 0xca, + 0x28, 0x48, 0x56, 0x59, 0xfb, 0xa8, 0xd8, 0x2b, 0x70, 0x61, 0x22, 0x43, + 0x43, 0xb9, 0x60, 0x44, 0xeb, 0xf8, 0x98, 0x87, 0x25, 0x84, 0xa2, 0xaa, + 0x37, 0xd4, 0xb8, 0xd6, 0x3d, 0xa3, 0xa1, 0x4a, 0x81, 0xc2, 0xa9, 0xea, + 0xa2, 0xd6, 0x63, 0x76, 0x50, 0xeb, 0xcd, 0x19, 0x40, 0xb1, 0x7c, 0xf6, + 0xc1, 0x44, 0x01, 0x25, 0xe0, 0xdd, 0xb8, 0x39, 0xef, 0x46, 0x3d, 0x50, + 0x33, 0xed, 0xb1, 0x63, 0x65, 0xd7, 0x50, 0xe7, 0x95, 0xba, 0xab, 0xa7, + 0x14, 0xe5, 0x60, 0xcb, 0x81, 0x6e, 0x88, 0x3c, 0x06, 0x6e, 0x7d, 0x8e, + 0xe7, 0xbb, 0xa5, 0xc2, 0xbd, 0xae, 0x46, 0x8f, 0x43, 0x04, 0x29, 0xe6, + 0x17, 0x38, 0x05, 0x2d, 0x97, 0x93, 0x5b, 0xf9, 0xef, 0x4d, 0x2e, 0x75, + 0x6c, 0x69, 0xba, 0x08, 0xf2, 0x21, 0x1e, 0x21, 0xe6, 0x8a, 0x5b, 0x8c, + 0xd4, 0x8e, 0xde, 0x64, 0x9b, 0x9d, 0x54, 0x58, 0x65, 0x3e, 0xdd, 0x8a, + 0x1e, 0x81, 0x4e, 0x45, 0xe8, 0xfb, 0x20, 0xc3, 0x3a, 0xf0, 0x50, 0x1e, + 0x8a, 0x18, 0xea, 0x2b, 0xf5, 0xe1, 0xa6, 0xb6, 0xc8, 0xa0, 0x02, 0x3d, + 0x6e, 0xfa, 0x0b, 0x51, 0x95, 0x4e, 0x4c, 0x11, 0xb0, 0xc4, 0x62, 0x58, + 0xa6, 0x9c, 0x13, 0x4e, 0xbe, 0xc9, 0x29, 0x93, 0x29, 0x15, 0x5f, 0xaf, + 0x0e, 0xc3, 0xb3, 0x26, 0x3f, 0xdc, 0x4c, 0x33, 0xb8, 0x4b, 0x11, 0xae, + 0x1f, 0xd7, 0x05, 0x39, 0xcf, 0xfe, 0xc3, 0x6d, 0xf0, 0xc0, 0x77, 0x02, + 0xb8, 0x9b, 0x3d, 0x1b, 0x3d, 0x72, 0xfe, 0x7e, 0x18, 0x60, 0x9b, 0xc4, + 0x8b, 0xac, 0x25, 0x6d, 0x3b, 0x80, 0x34, 0xbc, 0x51, 0xaf, 0xf6, 0xff, + 0x66, 0x98, 0x86, 0x6e, 0x9e, 0x9a, 0xfe, 0x6d, 0x21, 0x4d, 0xf1, 0x58, + 0x3e, 0x3e, 0x43, 0xe3, 0x7e, 0x40, 0xb0, 0xb3, 0xd8, 0x12, 0xa5, 0xce, + 0x09, 0x41, 0x8c, 0x1d, 0x73, 0xcd, 0xfc, 0x63, 0xed, 0xeb, 0x08, 0x1e, + 0x34, 0xfb, 0xed, 0x75, 0xb7, 0x86, 0x84, 0x7c, 0x80, 0xe9, 0xe4, 0xa3, + 0x1c, 0x4a, 0x0d, 0x11, 0x16, 0x24, 0xb2, 0xb1, 0x99, 0xe5, 0xe3, 0x2e, + 0x2f, 0x70, 0xcd, 0x1e, 0x35, 0x14, 0x79, 0xba, 0xa2, 0x51, 0x7a, 0x29, + 0x5c, 0x75, 0x8f, 0xdd, 0x22, 0xdf, 0xb2, 0x64, 0xd9, 0x95, 0x11, 0x33, + 0x97, 0xee, 0x69, 0x42, 0x01, 0x96, 0x98, 0x1b, 0x43, 0xc2, 0xec, 0xf9, + 0xb0, 0xdb, 0x69, 0x34, 0xab, 0x98, 0x1b, 0xb2, 0x04, 0x05, 0x14, 0x1d, + 0x25, 0x2f, 0x32, 0x41, 0x50, 0x51, 0x55, 0x62, 0x6d, 0x78, 0x7f, 0x8b, + 0xbb, 0xc2, 0xcd, 0xcf, 0xe4, 0xed, 0x04, 0x1f, 0x25, 0x30, 0x43, 0x64, + 0x69, 0x7c, 0x87, 0xa3, 0xa9, 0xb1, 0xc1, 0xd1, 0xdc, 0x01, 0x10, 0x1d, + 0x27, 0x3f, 0x5c, 0x5d, 0x75, 0x82, 0x9b, 0xaa, 0xb3, 0xe8, 0x0c, 0x11, + 0x1f, 0x24, 0x38, 0x41, 0x45, 0x54, 0x5f, 0x69, 0x85, 0x8d, 0x93, 0x9e, + 0xc5, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x16, 0x25, 0x32, 0x42}; +const uint8_t expected_signature_65[] = { + 0x8b, 0x6f, 0x79, 0x00, 0xcc, 0x79, 0x57, 0xee, 0x16, 0x86, 0x87, 0xd5, + 0xcf, 0xb6, 0x90, 0x2c, 0xc6, 0x30, 0xeb, 0x8d, 0x39, 0xae, 0x9b, 0xf1, + 0x66, 0xe0, 0xd6, 0x93, 0xa5, 0x4e, 0x26, 0x9b, 0x96, 0x8f, 0xd1, 0x46, + 0x97, 0xbe, 0x71, 0x1c, 0xf3, 0xa5, 0xe5, 0xae, 0x8d, 0x4b, 0xf2, 0xe6, + 0x48, 0x8f, 0xe9, 0x5e, 0x07, 0xef, 0xe4, 0xbb, 0x39, 0xc1, 0xc9, 0x3c, + 0xc3, 0x0b, 0xfb, 0x2a, 0x29, 0x06, 0xfe, 0x01, 0xcb, 0x63, 0x83, 0x10, + 0xa8, 0xc8, 0xa0, 0x29, 0xa5, 0x80, 0xeb, 0xbd, 0xa9, 0xd9, 0x0b, 0x61, + 0xbc, 0xce, 0x11, 0x55, 0x66, 0x12, 0xc7, 0x5b, 0xd2, 0x7a, 0x5a, 0xc8, + 0xab, 0xab, 0xbf, 0x3a, 0x1f, 0x96, 0x1a, 0x70, 0xcb, 0x41, 0x5f, 0xc8, + 0xb7, 0x09, 0x22, 0x98, 0x9b, 0xb8, 0xf7, 0x2d, 0x49, 0x65, 0x1d, 0x09, + 0x8b, 0x70, 0xb5, 0x42, 0xc9, 0x89, 0x5b, 0x74, 0xb4, 0x28, 0x82, 0x01, + 0x53, 0x12, 0x3e, 0x23, 0xf6, 0x54, 0xf8, 0x51, 0x12, 0x4b, 0x02, 0x3a, + 0x7e, 0xb6, 0x1f, 0xac, 0xa0, 0xe6, 0x6f, 0xf8, 0x61, 0x82, 0xe4, 0xfb, + 0x96, 0x2a, 0xd2, 0xaf, 0x3c, 0xea, 0x6e, 0xdc, 0x18, 0x8a, 0x5d, 0x90, + 0xda, 0xa2, 0x5d, 0xa7, 0x8f, 0x5b, 0x50, 0x46, 0xaf, 0x8c, 0x17, 0x6a, + 0x4c, 0x39, 0xfc, 0x31, 0x4c, 0x4b, 0xc2, 0x57, 0x66, 0x61, 0x98, 0xbf, + 0xe6, 0xfb, 0x54, 0x96, 0xd3, 0x70, 0xb8, 0xaf, 0xcd, 0x8b, 0xcc, 0x00, + 0x07, 0x92, 0x15, 0xc2, 0xbb, 0x48, 0xbb, 0xc6, 0xb7, 0xb5, 0x58, 0x8c, + 0xfc, 0xf0, 0xda, 0x6a, 0x0d, 0xf7, 0x1d, 0x7d, 0xc6, 0x27, 0x26, 0x1a, + 0x99, 0xc5, 0x2f, 0xf8, 0x97, 0x65, 0x43, 0x86, 0xd6, 0x25, 0x23, 0x2b, + 0x06, 0x8f, 0x12, 0xa1, 0xae, 0xbb, 0x58, 0x34, 0x25, 0xec, 0x5b, 0x68, + 0xa4, 0xe1, 0x03, 0xfc, 0x26, 0xa2, 0xd6, 0x2b, 0x61, 0x10, 0x47, 0xbd, + 0x16, 0xe5, 0xca, 0x4a, 0xce, 0xed, 0x89, 0x09, 0x1a, 0xed, 0x22, 0xc1, + 0xca, 0x44, 0xe3, 0xef, 0x72, 0x34, 0xab, 0xab, 0x61, 0x5c, 0x9f, 0x5f, + 0xb5, 0xf5, 0xe8, 0x2d, 0x89, 0xea, 0x4b, 0x40, 0x65, 0x57, 0x8b, 0xa2, + 0x95, 0x40, 0x9c, 0x72, 0xc0, 0x46, 0x69, 0x45, 0x06, 0xf6, 0x07, 0x5b, + 0x2d, 0xa5, 0x46, 0xca, 0x5d, 0xfb, 0x40, 0xb7, 0x48, 0x59, 0x5b, 0xe2, + 0x1b, 0x38, 0xb2, 0x15, 0x75, 0x66, 0x67, 0x58, 0x00, 0x3f, 0xde, 0x8a, + 0x63, 0x13, 0x34, 0x6a, 0x30, 0xca, 0xb4, 0xd5, 0x3e, 0xe0, 0x6d, 0x14, + 0xb8, 0x9a, 0x48, 0xef, 0xfd, 0xbd, 0x6d, 0x20, 0x11, 0x4d, 0x25, 0xe5, + 0xab, 0x15, 0x8d, 0xe5, 0x91, 0xbc, 0xc6, 0x69, 0x8a, 0xf8, 0xab, 0x3a, + 0x82, 0xae, 0xc5, 0x03, 0x2c, 0xcf, 0x54, 0xdc, 0xcd, 0xe8, 0x49, 0x53, + 0xb5, 0xd8, 0xc2, 0x24, 0xf8, 0x8c, 0x38, 0x8f, 0xe3, 0xfe, 0x3a, 0x18, + 0x15, 0xa8, 0xda, 0x77, 0xc8, 0x81, 0x72, 0xc6, 0xc1, 0x60, 0xa3, 0x73, + 0x65, 0x68, 0x5c, 0xf3, 0x1d, 0x8d, 0x61, 0x21, 0x65, 0xfb, 0x45, 0xc4, + 0x4c, 0x31, 0x88, 0x25, 0x0d, 0x52, 0x75, 0x3b, 0xec, 0x54, 0xe0, 0xb1, + 0x9c, 0x7c, 0xdf, 0xe3, 0x3b, 0x77, 0x31, 0x33, 0xd7, 0x25, 0x99, 0xff, + 0xc5, 0x40, 0x1e, 0x85, 0x09, 0xfd, 0x2d, 0x24, 0x4a, 0x92, 0xe7, 0x77, + 0x48, 0xa5, 0x46, 0xf4, 0x8e, 0xa3, 0x6b, 0x24, 0xe4, 0x6b, 0x31, 0xf6, + 0xe0, 0x16, 0x49, 0x9b, 0x9f, 0xa3, 0x1a, 0x5c, 0x05, 0x5e, 0x81, 0x62, + 0xc8, 0x14, 0x52, 0xb4, 0x21, 0xfd, 0x76, 0x6d, 0x88, 0xe9, 0x3b, 0x0b, + 0x75, 0x27, 0x92, 0x47, 0x5a, 0x58, 0x08, 0x26, 0xa7, 0xa2, 0x48, 0x1c, + 0x14, 0x3e, 0x5e, 0xdf, 0x81, 0x83, 0x83, 0x3e, 0xc6, 0x72, 0x27, 0xc4, + 0x6a, 0x46, 0x2b, 0xf2, 0x8d, 0x42, 0x11, 0xb9, 0x15, 0xd7, 0xf0, 0x20, + 0x29, 0x53, 0xba, 0xf0, 0x6e, 0x41, 0x3d, 0xee, 0x19, 0xf2, 0x43, 0xf3, + 0x6d, 0x00, 0xe2, 0x43, 0x77, 0xb9, 0xa9, 0x78, 0x34, 0x48, 0x3c, 0x1a, + 0x8b, 0xbd, 0xa1, 0xe5, 0x90, 0x59, 0x5b, 0xd6, 0x1e, 0x22, 0xdf, 0xb2, + 0xa7, 0x96, 0x7d, 0x55, 0x86, 0x66, 0x95, 0xb7, 0x06, 0xe7, 0x60, 0x2a, + 0x01, 0x48, 0x3f, 0xd4, 0xa7, 0xd4, 0xc2, 0x38, 0xa4, 0x10, 0x8e, 0x4f, + 0x97, 0xad, 0xa3, 0xb9, 0xe2, 0xaa, 0x13, 0xb1, 0x16, 0x89, 0x3d, 0x74, + 0x60, 0x94, 0x8c, 0xc3, 0xe6, 0x5f, 0xcf, 0xdc, 0x58, 0x17, 0x98, 0x27, + 0x86, 0xae, 0x2a, 0x0d, 0xe8, 0x33, 0x79, 0xc8, 0xc8, 0x5b, 0x59, 0xb0, + 0xba, 0xac, 0xd3, 0x6e, 0x2d, 0x7b, 0x0b, 0x9a, 0xb5, 0xfd, 0x58, 0x42, + 0xeb, 0x80, 0xf4, 0x6b, 0x9a, 0x2f, 0x19, 0x43, 0x75, 0xb4, 0xcb, 0xc9, + 0xd5, 0x28, 0xf5, 0xb9, 0x67, 0x82, 0xb4, 0xed, 0x8c, 0x3f, 0x3d, 0x6b, + 0x6d, 0x1b, 0x80, 0x13, 0x5c, 0x7b, 0x2e, 0xfa, 0xa0, 0x32, 0xba, 0xb5, + 0x46, 0xd6, 0xe7, 0x90, 0xe9, 0xd1, 0x91, 0xa0, 0xaa, 0x26, 0x35, 0xa2, + 0x0d, 0x98, 0x44, 0x11, 0xae, 0xf9, 0xc5, 0x12, 0x4d, 0x1a, 0x7c, 0x53, + 0xea, 0xf6, 0x05, 0x8d, 0x3a, 0x74, 0x92, 0xc9, 0x65, 0xeb, 0x6f, 0xb5, + 0xb4, 0xd2, 0xcd, 0x5c, 0xec, 0xaf, 0x95, 0xcb, 0xb4, 0x3c, 0x22, 0xca, + 0x1c, 0x06, 0x85, 0x16, 0x96, 0x24, 0x8c, 0x6c, 0x80, 0xf8, 0xb3, 0xa7, + 0x87, 0x77, 0xeb, 0x09, 0x71, 0xc8, 0x95, 0xfb, 0x5e, 0xe5, 0x6f, 0x78, + 0xf9, 0x60, 0xf9, 0x9e, 0x58, 0x7b, 0xbd, 0x47, 0xdd, 0x48, 0x2e, 0x56, + 0xcd, 0x63, 0x72, 0xc9, 0x4b, 0x65, 0x2d, 0x41, 0xe8, 0x81, 0x19, 0x33, + 0x4b, 0xf6, 0x02, 0xc6, 0xcb, 0x2e, 0xdf, 0x3d, 0xc8, 0xdd, 0x2f, 0x0f, + 0x09, 0x67, 0xf0, 0xaa, 0x3c, 0x51, 0xdc, 0x8d, 0xc6, 0xc3, 0xb2, 0x3b, + 0x15, 0x85, 0xcb, 0xeb, 0x62, 0xef, 0xa3, 0xf9, 0x94, 0xf4, 0x35, 0x9c, + 0x59, 0xcc, 0xc2, 0x68, 0xb4, 0xde, 0x02, 0x75, 0x8e, 0xf5, 0x33, 0xca, + 0xd5, 0xc5, 0x24, 0xae, 0xf6, 0xde, 0x2b, 0x01, 0xf4, 0x56, 0xb9, 0xa5, + 0xa7, 0xe0, 0x64, 0x2e, 0xba, 0x1d, 0x53, 0x54, 0x46, 0xcf, 0x64, 0x16, + 0x12, 0xe2, 0xa6, 0xcc, 0x18, 0xb4, 0x77, 0x8b, 0x19, 0x50, 0x43, 0x96, + 0xc8, 0x5d, 0xc3, 0x58, 0xf0, 0xfd, 0x5e, 0x13, 0xa9, 0x10, 0x67, 0xdf, + 0x25, 0xdb, 0xaf, 0x38, 0x5f, 0xbd, 0x35, 0xc1, 0x49, 0x44, 0xe8, 0x1f, + 0x12, 0xa4, 0x7c, 0x28, 0xa3, 0xd6, 0x0d, 0x6f, 0x44, 0xa9, 0x5f, 0xfc, + 0x9f, 0xfa, 0x11, 0x62, 0x87, 0x5b, 0x0e, 0x91, 0xd4, 0xb6, 0xd3, 0x71, + 0xc2, 0x77, 0x19, 0xf6, 0x7c, 0x11, 0x30, 0x5e, 0x5c, 0xd3, 0x1e, 0x90, + 0x05, 0x31, 0x63, 0xbb, 0xef, 0x85, 0xe0, 0x27, 0x94, 0x80, 0xcb, 0x33, + 0xbc, 0x5e, 0x45, 0x87, 0x62, 0xdf, 0xd4, 0x12, 0x2f, 0xf5, 0x41, 0x15, + 0x03, 0x0c, 0x80, 0xe8, 0xe2, 0x06, 0xde, 0x4b, 0x46, 0x70, 0x94, 0xd2, + 0x0d, 0x85, 0x72, 0x27, 0xe5, 0x6c, 0xeb, 0xd2, 0x78, 0x0b, 0x38, 0x40, + 0xe8, 0xdb, 0x47, 0x5c, 0xba, 0xd0, 0x21, 0x33, 0x8f, 0xb8, 0xc0, 0x66, + 0x1e, 0xd1, 0xb0, 0x94, 0xa3, 0x39, 0xc7, 0x87, 0xaf, 0x97, 0x98, 0xce, + 0x6d, 0x03, 0x1a, 0xdb, 0x52, 0x96, 0x0b, 0x9d, 0x5b, 0xf8, 0xa3, 0xf4, + 0x41, 0x95, 0x72, 0xad, 0x0e, 0x98, 0x61, 0x7f, 0xf3, 0x8f, 0x23, 0xeb, + 0xc0, 0xdf, 0xd7, 0x70, 0x26, 0x8c, 0xb3, 0xb3, 0xf0, 0xa2, 0x8a, 0x39, + 0xdd, 0x61, 0xb4, 0x53, 0xe0, 0x2a, 0x6f, 0x91, 0x34, 0x9c, 0x76, 0xf6, + 0x52, 0x93, 0xe6, 0x39, 0xb7, 0x54, 0x07, 0x46, 0x82, 0x2d, 0x05, 0x6d, + 0x9a, 0x00, 0x53, 0x65, 0x68, 0x93, 0x91, 0x00, 0xda, 0xe0, 0x93, 0x34, + 0x60, 0xb1, 0x93, 0x0b, 0x64, 0xa8, 0x12, 0xd2, 0x51, 0x3c, 0xdb, 0xb0, + 0x4c, 0x39, 0x4e, 0xce, 0xbd, 0xf0, 0x65, 0x12, 0x8a, 0xd4, 0x80, 0x7d, + 0x82, 0x85, 0xe4, 0x92, 0xc2, 0x77, 0x1e, 0xcf, 0xd9, 0xab, 0x0f, 0x9b, + 0x32, 0x2e, 0x3f, 0xe1, 0x0e, 0x87, 0x1c, 0x87, 0x34, 0xe7, 0x93, 0x16, + 0x95, 0x09, 0x7d, 0x24, 0xa8, 0xb5, 0xe0, 0x9f, 0x23, 0x87, 0x5c, 0x0b, + 0x31, 0x4a, 0x2f, 0xe2, 0x5c, 0x82, 0x49, 0x51, 0xe4, 0x93, 0xcb, 0x05, + 0x23, 0x4f, 0x8a, 0x83, 0x88, 0xfb, 0x89, 0xb0, 0x08, 0xd6, 0x64, 0xad, + 0x51, 0x84, 0x40, 0x29, 0xb1, 0xca, 0x74, 0x26, 0x29, 0x5a, 0x61, 0x01, + 0x2e, 0xa0, 0xeb, 0xeb, 0x02, 0xb5, 0xff, 0xd8, 0x20, 0x6a, 0x5e, 0x8d, + 0x17, 0x1e, 0xa3, 0xd7, 0x2f, 0x20, 0x0b, 0x93, 0x17, 0x24, 0xf7, 0x90, + 0x7b, 0xc6, 0xba, 0xd8, 0xf9, 0xe9, 0x0a, 0x2a, 0x7a, 0x81, 0x23, 0x81, + 0x03, 0x6f, 0x1e, 0x0d, 0x87, 0x83, 0xd1, 0xcf, 0x92, 0x2f, 0x19, 0x82, + 0x4e, 0x6c, 0x0a, 0x02, 0xb6, 0x70, 0xbc, 0xe1, 0x58, 0xe7, 0x16, 0xdb, + 0x2f, 0x74, 0x9f, 0xe1, 0xc2, 0x1e, 0x64, 0xc6, 0x48, 0x08, 0xee, 0xea, + 0x52, 0x9a, 0xce, 0x2c, 0xc5, 0x0c, 0x7a, 0x63, 0xf1, 0x6a, 0xbd, 0x2c, + 0x8b, 0xd5, 0x4a, 0xfa, 0x1e, 0xab, 0x9a, 0x5b, 0x25, 0xb8, 0xfa, 0x0a, + 0xe9, 0x68, 0x80, 0x6f, 0x80, 0x57, 0x10, 0x54, 0xb8, 0xa2, 0x16, 0xbd, + 0xfe, 0xf7, 0xea, 0x01, 0xc7, 0x94, 0x5a, 0x95, 0xe3, 0x61, 0xa5, 0x49, + 0x84, 0xf5, 0x79, 0x78, 0xb5, 0x0a, 0x96, 0xca, 0x01, 0x1b, 0xd0, 0x0b, + 0x51, 0x30, 0xd3, 0x48, 0xfc, 0x4d, 0x50, 0x71, 0x09, 0x73, 0xea, 0x37, + 0xcd, 0x9d, 0x3d, 0xde, 0x30, 0x56, 0x21, 0xf0, 0xef, 0x84, 0xad, 0x27, + 0xe1, 0x83, 0xdb, 0xfb, 0xcd, 0x11, 0xb2, 0xbd, 0x30, 0x67, 0x8a, 0x88, + 0x09, 0x0e, 0x9d, 0x96, 0x09, 0xba, 0xda, 0x9d, 0xf0, 0xe9, 0xb4, 0xa6, + 0x7a, 0x04, 0xf9, 0x4b, 0xb8, 0x51, 0xa9, 0x99, 0xf3, 0xbb, 0x77, 0x95, + 0x0a, 0xa1, 0xa6, 0xa1, 0x24, 0xfc, 0xcc, 0x45, 0xe8, 0x83, 0xc8, 0x6f, + 0x48, 0xad, 0x9a, 0x73, 0xd0, 0xe0, 0x57, 0x7d, 0xe4, 0x78, 0x65, 0xef, + 0xae, 0xc2, 0xfe, 0x7a, 0x56, 0xaf, 0x03, 0x71, 0x2b, 0xe6, 0xa1, 0x7e, + 0xe5, 0x12, 0xf8, 0xc3, 0x75, 0xc7, 0x22, 0x5f, 0x1b, 0x52, 0x90, 0xe5, + 0xdf, 0xba, 0x9d, 0xe2, 0x68, 0xe0, 0xb3, 0x7a, 0x9e, 0x14, 0xff, 0xb5, + 0x0a, 0x80, 0x20, 0x49, 0x88, 0xe9, 0x9c, 0xe4, 0xb5, 0xaf, 0x7e, 0x51, + 0xec, 0xe7, 0xfc, 0x64, 0x65, 0x21, 0x10, 0xc6, 0x1f, 0x7f, 0x93, 0x7d, + 0xd8, 0xf5, 0xd0, 0x98, 0x94, 0x44, 0xf8, 0x49, 0x6a, 0x51, 0x0a, 0x54, + 0xf4, 0x9f, 0xee, 0x3c, 0x56, 0xbf, 0x4c, 0xe4, 0xde, 0x1c, 0x9b, 0x11, + 0x7e, 0x9a, 0x71, 0x11, 0x80, 0x33, 0xd5, 0xb0, 0x9b, 0xef, 0x67, 0x29, + 0xa4, 0x7d, 0x70, 0x31, 0x3f, 0x8b, 0x2e, 0x4a, 0x0f, 0x2c, 0x91, 0x3d, + 0x3e, 0x3d, 0x8c, 0x0a, 0x2b, 0xf1, 0xdd, 0xbf, 0x61, 0xe6, 0xa3, 0xef, + 0x6d, 0x82, 0xc8, 0xb7, 0x5e, 0x2b, 0x83, 0xc9, 0x4e, 0xa0, 0x85, 0x7f, + 0x01, 0x5a, 0xca, 0x6e, 0x90, 0xfa, 0x7e, 0x82, 0x4d, 0x35, 0x7e, 0xe0, + 0x26, 0x40, 0xf4, 0xa6, 0xae, 0xc3, 0x89, 0xf3, 0xca, 0x55, 0x2c, 0xb5, + 0x29, 0x05, 0x94, 0x45, 0xa7, 0x45, 0xf3, 0x3d, 0xbb, 0x53, 0x5e, 0xca, + 0x7c, 0x84, 0x8f, 0x72, 0x98, 0x93, 0x90, 0x1f, 0x56, 0x72, 0xdb, 0xbd, + 0xa9, 0xeb, 0xf9, 0xe9, 0xce, 0xb1, 0x41, 0xc3, 0xaa, 0xa0, 0xc4, 0x74, + 0x23, 0xc1, 0xeb, 0x7d, 0x41, 0xcd, 0xa4, 0x62, 0xec, 0xfc, 0x9a, 0xa4, + 0x16, 0xec, 0x67, 0x41, 0x89, 0xf0, 0x0e, 0xf3, 0xd1, 0xa2, 0x2f, 0xba, + 0x5d, 0x93, 0x36, 0x46, 0xf5, 0x52, 0x64, 0x91, 0xe7, 0x40, 0x91, 0x20, + 0xa1, 0xc9, 0xaa, 0x4c, 0x79, 0xc4, 0xbb, 0x67, 0x79, 0xad, 0x43, 0xab, + 0xba, 0xde, 0xfc, 0xf1, 0x74, 0x81, 0x33, 0xc0, 0x3f, 0x39, 0xd1, 0xd1, + 0xdf, 0xc0, 0x53, 0x33, 0xb2, 0x92, 0x37, 0xe6, 0x86, 0x2a, 0xe4, 0xe1, + 0x7c, 0x98, 0xf7, 0xdb, 0x5c, 0xa9, 0xff, 0x8d, 0x9c, 0xab, 0xe2, 0xf2, + 0xd5, 0xb1, 0x42, 0xa9, 0xf4, 0x97, 0x80, 0xcd, 0xde, 0x25, 0x2e, 0x87, + 0x92, 0xdd, 0xcf, 0xed, 0x67, 0x93, 0x8c, 0x5a, 0x1d, 0xee, 0xcf, 0x9d, + 0x50, 0x8f, 0xa7, 0xe3, 0x5c, 0xa3, 0x68, 0x78, 0x24, 0xeb, 0x60, 0xa3, + 0x8b, 0x36, 0xbb, 0xcb, 0x46, 0xee, 0x77, 0xfb, 0xf8, 0x69, 0x24, 0xd1, + 0xfa, 0xad, 0x76, 0x76, 0x5e, 0x54, 0xe5, 0xb6, 0x36, 0xc6, 0xdd, 0xa9, + 0x6c, 0x44, 0x15, 0xf7, 0x0a, 0xf8, 0xbb, 0xba, 0xec, 0x35, 0xff, 0xc9, + 0xd6, 0x5d, 0xf5, 0x73, 0x4a, 0x15, 0x8f, 0x7b, 0x6e, 0xf4, 0xa0, 0x6d, + 0x10, 0xbb, 0x67, 0x0c, 0xb4, 0x69, 0xad, 0xb6, 0x40, 0xf7, 0x5f, 0x37, + 0x28, 0xc4, 0x08, 0x49, 0xd0, 0x16, 0x70, 0x80, 0xea, 0x55, 0x66, 0x07, + 0xc8, 0x03, 0x1b, 0xf6, 0xd3, 0x03, 0x04, 0x74, 0xe0, 0x50, 0x3f, 0xd2, + 0x53, 0x92, 0xa0, 0x9d, 0x59, 0xc9, 0x74, 0xf2, 0x7e, 0x3b, 0x33, 0x02, + 0x10, 0x0b, 0x39, 0xf7, 0x4f, 0x6b, 0x58, 0xb2, 0x1a, 0xda, 0x65, 0x44, + 0xd1, 0x7c, 0x3f, 0xd7, 0xe3, 0xac, 0xe2, 0x1f, 0x38, 0xc1, 0x6a, 0xb0, + 0xdc, 0xc3, 0x9c, 0x7b, 0x11, 0x3c, 0x05, 0x21, 0x96, 0x76, 0x98, 0x76, + 0x82, 0xc1, 0x54, 0xdf, 0xdc, 0x8f, 0x4c, 0xd2, 0x63, 0x04, 0x06, 0x77, + 0x36, 0xe6, 0x2e, 0xd1, 0x00, 0x28, 0x42, 0x7c, 0x4a, 0x27, 0x90, 0x46, + 0xc9, 0xce, 0x33, 0x1c, 0xae, 0xda, 0x79, 0x64, 0x7f, 0x52, 0x3f, 0x58, + 0x11, 0x76, 0x4a, 0xb6, 0x72, 0xd8, 0x76, 0xae, 0xfd, 0x5c, 0x57, 0x69, + 0x76, 0x91, 0x84, 0x21, 0xc4, 0x9b, 0xd8, 0xa2, 0xff, 0x93, 0x02, 0x77, + 0x61, 0x57, 0x96, 0x7b, 0x8e, 0xfc, 0xf2, 0x6c, 0x11, 0x2b, 0x5e, 0x88, + 0x5c, 0x17, 0x1d, 0x12, 0x79, 0x3a, 0x78, 0xb6, 0x9d, 0x70, 0xfa, 0xd4, + 0xc1, 0x5c, 0x90, 0x0e, 0x0a, 0xd1, 0x3c, 0x7d, 0xcf, 0xee, 0x8a, 0xb2, + 0xb2, 0x4d, 0xce, 0x89, 0x32, 0xa9, 0x6c, 0x56, 0x57, 0x85, 0xb1, 0xbf, + 0x18, 0x1d, 0xc6, 0xe1, 0x17, 0xc5, 0x92, 0x42, 0x99, 0xf9, 0x9f, 0x04, + 0xec, 0x38, 0xf8, 0xa0, 0xd2, 0xab, 0xe6, 0x13, 0x4d, 0x9c, 0x18, 0x86, + 0x3e, 0x18, 0x73, 0x2c, 0xac, 0xe0, 0xb9, 0xf9, 0x87, 0x74, 0xb8, 0xd7, + 0x47, 0x6e, 0x42, 0xfc, 0x29, 0xa0, 0x1f, 0x56, 0x68, 0xb6, 0x23, 0x96, + 0xa2, 0x8d, 0x54, 0x81, 0x0f, 0x60, 0xb9, 0xde, 0x93, 0xfc, 0xfd, 0xde, + 0xbe, 0xb3, 0xb5, 0x87, 0xec, 0x9f, 0x17, 0xc2, 0x77, 0x6e, 0xa0, 0x62, + 0xdb, 0x66, 0xba, 0xc5, 0x05, 0x12, 0x46, 0x5d, 0x3c, 0x23, 0x29, 0x68, + 0xe5, 0x31, 0xe3, 0x15, 0xec, 0xac, 0x15, 0x9a, 0xbf, 0x42, 0x65, 0x80, + 0x45, 0x9c, 0x1d, 0xc2, 0x0e, 0x18, 0x47, 0x40, 0x44, 0xc1, 0x55, 0x24, + 0x5a, 0x35, 0xad, 0x59, 0xd2, 0xc6, 0xc3, 0x68, 0x58, 0xbd, 0x6f, 0xcf, + 0x5d, 0xb1, 0x9b, 0x0c, 0x92, 0x39, 0x22, 0x49, 0x66, 0x2e, 0x03, 0x7b, + 0x75, 0x5c, 0x6c, 0xde, 0x37, 0x54, 0xa9, 0x07, 0x2f, 0x7e, 0xc1, 0x3e, + 0x3b, 0xab, 0xd2, 0xa9, 0xfa, 0xc7, 0x6b, 0xd5, 0x14, 0x08, 0x35, 0x89, + 0x0b, 0x31, 0x18, 0x54, 0x7d, 0x6b, 0x53, 0x80, 0x6e, 0x32, 0x9b, 0xff, + 0x61, 0x7f, 0x36, 0xe5, 0x28, 0x40, 0xbc, 0xc7, 0x19, 0xb3, 0xae, 0xfa, + 0x95, 0xa8, 0xae, 0xd2, 0x97, 0x72, 0xc6, 0x91, 0x36, 0x3a, 0xa6, 0xec, + 0x4a, 0x41, 0x63, 0x6b, 0x28, 0xef, 0x5a, 0xa1, 0xdb, 0xf2, 0xd9, 0xfd, + 0x61, 0x72, 0xa4, 0xd2, 0x9e, 0xf7, 0x47, 0xf4, 0x4e, 0xea, 0x2a, 0xa5, + 0x35, 0xe1, 0x77, 0x3a, 0x53, 0x28, 0xa6, 0x55, 0x48, 0x0c, 0x1e, 0x44, + 0xfc, 0xc1, 0x31, 0x5a, 0x00, 0xcd, 0x29, 0xc1, 0x5c, 0xca, 0x2a, 0x07, + 0x01, 0x63, 0xac, 0xb3, 0xfb, 0xf6, 0x0b, 0xac, 0xfd, 0xe8, 0x7b, 0xed, + 0xf9, 0x3d, 0x9a, 0xbc, 0x67, 0x28, 0x1c, 0xd9, 0x3f, 0x97, 0x28, 0x4a, + 0xe7, 0xd0, 0x08, 0xe9, 0x3e, 0xa0, 0xcb, 0x0f, 0xe0, 0x3f, 0x1b, 0x80, + 0x43, 0x74, 0xd9, 0x9d, 0x0b, 0x22, 0x81, 0xf7, 0xec, 0x71, 0x2a, 0x29, + 0x9e, 0x5d, 0x1e, 0x8d, 0xf4, 0x22, 0x95, 0x78, 0x86, 0xcb, 0xf0, 0x9d, + 0xe7, 0x6a, 0x66, 0x7e, 0x28, 0xb5, 0x47, 0xb6, 0xdc, 0x0d, 0x03, 0x3c, + 0x09, 0x58, 0x76, 0x93, 0x39, 0xb2, 0xd3, 0x75, 0xb4, 0x51, 0x55, 0x84, + 0x30, 0x24, 0x0a, 0x76, 0xf4, 0x97, 0xe7, 0x0f, 0x5a, 0x67, 0xee, 0xf4, + 0xc7, 0x69, 0x8d, 0xf2, 0x32, 0x29, 0x5c, 0x33, 0x82, 0x5f, 0x6c, 0x47, + 0xd0, 0xe2, 0xbd, 0x62, 0xd6, 0x4c, 0x6d, 0x0d, 0xba, 0x87, 0xd3, 0x43, + 0x7e, 0x2d, 0xa6, 0x14, 0x09, 0x4f, 0x3b, 0xc3, 0x04, 0x14, 0xe5, 0x65, + 0xe9, 0x3b, 0x6a, 0xca, 0xb5, 0x96, 0x84, 0x3f, 0x53, 0x49, 0x22, 0x45, + 0x91, 0xff, 0xf9, 0x26, 0x75, 0x0d, 0x9c, 0xa7, 0x00, 0xf4, 0x65, 0xc4, + 0x60, 0x72, 0xab, 0xeb, 0xf8, 0xa8, 0x72, 0xfe, 0xd8, 0xde, 0x93, 0x67, + 0xcb, 0x09, 0xcc, 0xa0, 0xce, 0x9f, 0x67, 0x63, 0x26, 0xfa, 0x7f, 0x89, + 0xaa, 0x3e, 0x6d, 0xb2, 0x90, 0xd7, 0xef, 0x3e, 0x2a, 0x66, 0x26, 0x33, + 0xe6, 0x26, 0xc1, 0x58, 0xf8, 0x91, 0xea, 0x2f, 0xd0, 0x84, 0x21, 0x41, + 0x93, 0xa6, 0x36, 0x40, 0xb5, 0x4c, 0xac, 0x21, 0x88, 0x37, 0x47, 0x8a, + 0xb8, 0xf3, 0x33, 0x73, 0x12, 0xd7, 0x5a, 0x55, 0xf9, 0xd1, 0x1e, 0x75, + 0xa4, 0x66, 0x68, 0x3f, 0xf7, 0xb2, 0xc4, 0x5d, 0x1b, 0xb1, 0x61, 0x0f, + 0xaf, 0x4b, 0x9b, 0x20, 0x2b, 0x05, 0x68, 0x1c, 0x6c, 0x97, 0x8d, 0xb8, + 0x7b, 0x96, 0xda, 0xe0, 0x67, 0x15, 0x4c, 0x51, 0x71, 0x0d, 0xd3, 0x7b, + 0xde, 0xaa, 0xd3, 0x58, 0xf5, 0xc9, 0x62, 0x0a, 0xc2, 0x33, 0x1f, 0xf3, + 0xc3, 0x30, 0xb5, 0x64, 0xd1, 0x59, 0x41, 0x0e, 0xae, 0xaa, 0x0d, 0xdf, + 0x9f, 0x5d, 0x3f, 0x15, 0x0d, 0x46, 0x7a, 0x6d, 0x2e, 0x29, 0x1b, 0xc0, + 0xd3, 0x11, 0x10, 0x5d, 0xdc, 0x6a, 0x35, 0x8c, 0x43, 0xc8, 0x9f, 0x05, + 0x80, 0xdc, 0x25, 0x24, 0x37, 0x70, 0x7e, 0x1c, 0xe9, 0x85, 0x5a, 0xef, + 0x83, 0x3a, 0x55, 0x68, 0x83, 0x17, 0xf4, 0xc7, 0xae, 0xe4, 0x84, 0xc9, + 0x64, 0x5d, 0x2f, 0xb6, 0xca, 0x10, 0x95, 0xb8, 0xd6, 0x80, 0xfd, 0x05, + 0xa5, 0x06, 0x32, 0x34, 0x91, 0x01, 0xd2, 0x02, 0x90, 0xe1, 0xf7, 0x89, + 0x8a, 0xee, 0x18, 0x04, 0x93, 0xd9, 0xb4, 0x63, 0x4b, 0xf7, 0x7a, 0x9c, + 0x1b, 0x4b, 0xf9, 0x31, 0x32, 0xd9, 0xf2, 0x55, 0x4e, 0xc1, 0x02, 0xce, + 0x77, 0x38, 0x36, 0x29, 0xb8, 0x54, 0x8c, 0xc2, 0x27, 0x5f, 0xd9, 0xae, + 0x3e, 0x1e, 0xcd, 0xe9, 0x07, 0x90, 0x4c, 0xe0, 0xda, 0x16, 0x6e, 0xdf, + 0xde, 0x3a, 0x61, 0x89, 0x9f, 0x79, 0xd0, 0xd4, 0x66, 0x95, 0xad, 0xe4, + 0x11, 0x7d, 0xa1, 0xae, 0xec, 0x3e, 0x6e, 0x20, 0x5a, 0xd0, 0x28, 0x0e, + 0x55, 0xec, 0xcf, 0x34, 0xec, 0xb7, 0xfc, 0xa4, 0xb3, 0x8f, 0x56, 0x13, + 0x50, 0xcc, 0x15, 0x10, 0x74, 0x40, 0x72, 0x42, 0x20, 0x22, 0xb3, 0xaf, + 0xf3, 0x68, 0xba, 0x95, 0x45, 0xcb, 0xef, 0x92, 0xd5, 0x14, 0x4c, 0x1f, + 0xe3, 0xc1, 0xa6, 0x03, 0x4e, 0x05, 0xd2, 0x1a, 0xee, 0xd2, 0x48, 0x44, + 0x2e, 0x50, 0x3b, 0x86, 0xc8, 0x6a, 0xc8, 0x4c, 0xca, 0x2a, 0xb6, 0xf7, + 0x3c, 0xaf, 0xdc, 0x62, 0xb1, 0x49, 0x13, 0xfe, 0xe7, 0x32, 0xea, 0x78, + 0xfa, 0xba, 0xcf, 0x15, 0x47, 0x58, 0xdc, 0x19, 0x73, 0x1d, 0xff, 0xbd, + 0xcc, 0x27, 0xf6, 0xfc, 0x66, 0x68, 0xa7, 0x29, 0xaf, 0x2b, 0x25, 0x0c, + 0x15, 0x47, 0xff, 0xc1, 0x00, 0x9d, 0xfa, 0x58, 0x9c, 0xaa, 0xf9, 0xcc, + 0x4c, 0x51, 0x1d, 0xda, 0xf3, 0x3c, 0x10, 0xd0, 0x3b, 0x59, 0x30, 0x02, + 0x68, 0x29, 0x1c, 0xa7, 0x22, 0xea, 0x81, 0xd3, 0x29, 0x71, 0x39, 0xe8, + 0x72, 0x7f, 0x7d, 0x94, 0x0a, 0x64, 0x2c, 0xe6, 0x55, 0xfb, 0x90, 0x78, + 0x7e, 0x6c, 0x3e, 0xfe, 0x57, 0x14, 0x61, 0xef, 0xe2, 0x63, 0x57, 0x6c, + 0x13, 0x97, 0x27, 0x2b, 0x38, 0x44, 0xab, 0x74, 0x76, 0x11, 0xa6, 0x60, + 0xad, 0x8e, 0xad, 0xe5, 0xa5, 0xa1, 0x66, 0xc5, 0xe1, 0x4d, 0x27, 0xa0, + 0x79, 0x7a, 0x09, 0xe6, 0xf0, 0x28, 0x3f, 0xcb, 0xc6, 0xf8, 0x94, 0xc0, + 0xf1, 0x13, 0xbe, 0x62, 0x6a, 0x52, 0x75, 0x52, 0xd3, 0x82, 0x31, 0xbd, + 0x15, 0xf2, 0xe8, 0x2e, 0xb1, 0x62, 0x03, 0x1e, 0xe2, 0xb3, 0xec, 0xbc, + 0x3c, 0x12, 0xca, 0x62, 0x4e, 0xc2, 0x3a, 0x51, 0x1c, 0xdf, 0xa2, 0x84, + 0x88, 0xe5, 0x7e, 0xd7, 0x5d, 0xd7, 0xbf, 0xf2, 0x7d, 0xbd, 0x9a, 0x90, + 0x63, 0xfd, 0x8a, 0x84, 0x2b, 0x9d, 0x89, 0x27, 0x63, 0x4c, 0x0a, 0xe3, + 0x70, 0x94, 0x7b, 0xe6, 0xb3, 0xd7, 0xcb, 0xcb, 0x8a, 0xeb, 0x6b, 0x53, + 0x34, 0x2f, 0x62, 0x44, 0x2d, 0x73, 0x63, 0x8a, 0xf4, 0xa2, 0x01, 0xd7, + 0x12, 0xb6, 0x8d, 0x8c, 0x4b, 0x73, 0x2b, 0x44, 0x50, 0x49, 0x6f, 0x01, + 0xac, 0xc5, 0x15, 0x37, 0x6c, 0xde, 0xd4, 0x02, 0xb1, 0x12, 0x80, 0x73, + 0xb2, 0x52, 0x0e, 0xe0, 0xb5, 0x75, 0xc9, 0x48, 0xcf, 0x18, 0x5c, 0xcc, + 0xaf, 0x58, 0xa2, 0x3e, 0x28, 0xe4, 0xab, 0xde, 0xea, 0x2a, 0xcf, 0x58, + 0x22, 0xc4, 0x68, 0xea, 0x9b, 0x7b, 0x90, 0xc5, 0xdc, 0x1c, 0x37, 0xd1, + 0x8a, 0x4f, 0xe7, 0x24, 0x23, 0x39, 0xb9, 0x62, 0xb8, 0x41, 0x13, 0x7b, + 0xe2, 0x1e, 0x0d, 0x4e, 0x38, 0x11, 0xa3, 0xb9, 0x10, 0xbb, 0x10, 0x6f, + 0x40, 0x9f, 0x50, 0x05, 0xc7, 0x0e, 0xb9, 0x9e, 0xab, 0x7c, 0x3c, 0x78, + 0xce, 0x54, 0xbf, 0xbf, 0x40, 0x36, 0x76, 0xbc, 0x4b, 0x64, 0x32, 0xca, + 0x0e, 0x2d, 0x91, 0x87, 0xd5, 0x00, 0x19, 0xbf, 0x12, 0xd0, 0x35, 0x7c, + 0xa1, 0xe5, 0xcf, 0x7a, 0x2d, 0x08, 0x62, 0xed, 0x34, 0x61, 0xe3, 0xda, + 0x2c, 0xcc, 0x1b, 0xf8, 0x12, 0xfe, 0xfd, 0x19, 0xa2, 0xc3, 0x70, 0xfd, + 0x4f, 0x5b, 0x5d, 0x20, 0xd2, 0xe1, 0xc5, 0xac, 0xe7, 0xa1, 0x84, 0x00, + 0xbd, 0x46, 0x81, 0xfd, 0x54, 0x69, 0xed, 0x1a, 0x7a, 0x32, 0xbb, 0x75, + 0x22, 0x76, 0x6d, 0x34, 0x24, 0xcc, 0xe6, 0xbe, 0x78, 0x5a, 0x75, 0x6c, + 0xbc, 0x62, 0xb8, 0x14, 0xf7, 0x13, 0x73, 0xc2, 0xdc, 0xb6, 0xfa, 0xfb, + 0x97, 0xfe, 0x27, 0x7b, 0x33, 0xb8, 0xeb, 0x20, 0xd2, 0x0f, 0x4f, 0xed, + 0xd1, 0xd0, 0x63, 0xf7, 0xc5, 0x8e, 0xec, 0xcc, 0xd2, 0x31, 0x38, 0x35, + 0x65, 0x33, 0x5c, 0x63, 0x85, 0xf7, 0x3d, 0xc3, 0x62, 0x26, 0x52, 0x0a, + 0x67, 0xda, 0x87, 0x1f, 0x9e, 0x47, 0xec, 0x6b, 0xf5, 0x74, 0x1a, 0xc5, + 0xa7, 0xa0, 0x0f, 0xdd, 0xc5, 0x42, 0xf4, 0xda, 0x41, 0x1a, 0x48, 0xa9, + 0xbe, 0x4f, 0xb6, 0x28, 0x17, 0xe9, 0xf5, 0xd7, 0x00, 0xb3, 0xfe, 0x05, + 0x4e, 0xa7, 0xdf, 0x65, 0x7a, 0xb8, 0x4f, 0xe0, 0xfe, 0x58, 0x9e, 0xba, + 0x45, 0x11, 0xba, 0xc2, 0xdb, 0x97, 0x97, 0xa4, 0xbc, 0x18, 0x21, 0x1b, + 0xad, 0x82, 0xef, 0xb1, 0x5f, 0x2f, 0x25, 0x9d, 0xca, 0x52, 0xa5, 0x6d, + 0x8c, 0xab, 0x07, 0x2b, 0x7b, 0x6a, 0x77, 0x9d, 0xdf, 0xfb, 0xae, 0x6e, + 0x49, 0x18, 0x25, 0x4a, 0xf2, 0x7d, 0xa0, 0x32, 0xc8, 0x53, 0x10, 0xc3, + 0xf2, 0xef, 0xf3, 0xe7, 0x79, 0xd7, 0x6a, 0x0e, 0x61, 0xff, 0x89, 0xc9, + 0x42, 0xe8, 0x6e, 0x4f, 0x78, 0xe1, 0x5f, 0xcd, 0x7a, 0xf6, 0x27, 0x72, + 0x67, 0xea, 0x0b, 0xa6, 0xcc, 0x34, 0xb7, 0x8f, 0x92, 0x3c, 0x95, 0xb9, + 0x0a, 0x5d, 0x49, 0x2e, 0xb7, 0x7d, 0x31, 0x9c, 0x79, 0x61, 0x95, 0x9c, + 0x60, 0x56, 0x8d, 0x35, 0x00, 0xc5, 0x8b, 0xe6, 0x02, 0x0f, 0x26, 0x39, + 0x7b, 0x93, 0x94, 0xb1, 0xcd, 0xde, 0xed, 0xfa, 0x2a, 0x4b, 0x63, 0xa8, + 0x1b, 0x31, 0x43, 0x5e, 0x69, 0x7c, 0xd6, 0x15, 0x35, 0x9c, 0xa2, 0xd7, + 0xdf, 0x0e, 0x1a, 0x20, 0x50, 0xf5, 0x02, 0x21, 0x30, 0x35, 0x3c, 0x60, + 0x71, 0xad, 0xd0, 0xe3, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x10, 0x17, 0x1d, 0x22, 0x2d}; +const uint8_t expected_signature_87[] = { + 0xdf, 0xe6, 0xe1, 0xa5, 0x20, 0xc1, 0xac, 0x98, 0x55, 0x2c, 0xf2, 0x13, + 0x65, 0x42, 0xe2, 0xb0, 0x77, 0x5f, 0x15, 0x00, 0x8f, 0x14, 0x48, 0xa1, + 0xe3, 0xee, 0x81, 0x35, 0x15, 0x34, 0xad, 0x6e, 0x60, 0x85, 0x00, 0xf8, + 0x18, 0x53, 0x0d, 0xa0, 0xc5, 0x41, 0xc4, 0x48, 0x09, 0x1b, 0x34, 0x0c, + 0x0e, 0xcf, 0xc6, 0x3d, 0x38, 0x78, 0x8b, 0x69, 0xe5, 0x6f, 0x4d, 0x43, + 0xfa, 0xa6, 0x75, 0x26, 0x8a, 0x75, 0x97, 0x10, 0x6a, 0x1f, 0x3c, 0xa6, + 0x94, 0xa9, 0x93, 0x8f, 0xe5, 0x62, 0xbf, 0x94, 0xe4, 0xd0, 0x0d, 0x11, + 0x4d, 0x03, 0xe2, 0xd8, 0xdf, 0x68, 0xb7, 0x87, 0x62, 0xc9, 0xdc, 0xc9, + 0x36, 0x4f, 0xcc, 0xd1, 0xa4, 0xae, 0x7e, 0xa4, 0xb9, 0xaf, 0xaf, 0xf0, + 0x8a, 0xe6, 0xff, 0x83, 0xe7, 0x54, 0x22, 0x6e, 0x3f, 0x2e, 0xa0, 0x4f, + 0xa8, 0x31, 0x53, 0xf3, 0x62, 0xeb, 0x04, 0xfa, 0xd1, 0x57, 0x39, 0x43, + 0xf9, 0xe0, 0x31, 0x12, 0x45, 0x09, 0x8b, 0x9e, 0x1e, 0x7a, 0x2b, 0x85, + 0xee, 0xdd, 0xe8, 0x1e, 0xd7, 0xc0, 0x17, 0xb4, 0xd2, 0xdc, 0x36, 0xa9, + 0xe4, 0x49, 0x88, 0xbf, 0x71, 0x43, 0x9d, 0x3e, 0xd2, 0x10, 0xe7, 0x82, + 0xb5, 0xfe, 0xdd, 0x42, 0xc8, 0x1b, 0x11, 0xf6, 0x52, 0x23, 0x98, 0x83, + 0x48, 0xec, 0xec, 0x70, 0x8b, 0xe7, 0x49, 0x9a, 0xd7, 0xd9, 0x7b, 0x47, + 0x4e, 0xe2, 0x5e, 0x17, 0x1a, 0xa0, 0x0e, 0x60, 0x85, 0x3a, 0x30, 0x8c, + 0x1c, 0x26, 0xb4, 0xe1, 0xb5, 0x2b, 0x48, 0xf4, 0xb8, 0x93, 0x2f, 0x79, + 0x3a, 0x1e, 0xb6, 0x3b, 0x07, 0x3b, 0x1e, 0x15, 0xd7, 0x85, 0x5e, 0xd4, + 0x06, 0x0e, 0xcd, 0x6a, 0x93, 0x3a, 0x93, 0x29, 0x6a, 0xbe, 0x68, 0x8a, + 0xb6, 0xb8, 0xfa, 0xc5, 0x63, 0x48, 0x98, 0x10, 0x6d, 0xd9, 0xd3, 0x5b, + 0x29, 0x5f, 0x93, 0x90, 0x08, 0x1c, 0x1a, 0x15, 0x7b, 0x0a, 0x59, 0x9d, + 0x64, 0x24, 0x45, 0xb6, 0xd3, 0x7b, 0xc1, 0x5d, 0x74, 0x1f, 0x0b, 0x8e, + 0x18, 0xf2, 0x92, 0x8e, 0xd4, 0x7f, 0x72, 0x5c, 0x98, 0x1f, 0x8b, 0xa5, + 0xb8, 0xf4, 0x7e, 0x12, 0x6a, 0x93, 0xb9, 0xb5, 0xf1, 0xda, 0x97, 0x75, + 0x4f, 0x56, 0x80, 0x88, 0x64, 0x2b, 0xe0, 0x59, 0xcd, 0x5e, 0x91, 0x64, + 0x9c, 0x0c, 0xa8, 0xdd, 0xac, 0xcb, 0xf3, 0x48, 0x3b, 0x5c, 0xc4, 0xc5, + 0xb9, 0x9a, 0x0b, 0x8e, 0x5d, 0x9a, 0xd5, 0xb7, 0xf0, 0xd4, 0x07, 0x48, + 0xb9, 0x63, 0x02, 0x87, 0x8d, 0xae, 0x7e, 0x03, 0x33, 0x4f, 0x86, 0x15, + 0x1b, 0x3b, 0xdf, 0xda, 0xce, 0xd3, 0x1e, 0xc0, 0x76, 0xb5, 0x1c, 0xdd, + 0xb8, 0x32, 0x87, 0x7d, 0x59, 0x18, 0x72, 0x0c, 0xde, 0x8f, 0x63, 0x2d, + 0x38, 0xf2, 0xe9, 0xc2, 0x81, 0xed, 0xfa, 0x2d, 0x61, 0xef, 0x48, 0xdb, + 0xa2, 0xeb, 0xfe, 0x52, 0x31, 0x1e, 0x21, 0x0a, 0x08, 0xf6, 0x02, 0xd3, + 0xc0, 0x32, 0x3b, 0x6b, 0x2f, 0x64, 0xc4, 0xb3, 0x4b, 0xfe, 0x69, 0x78, + 0xbf, 0x20, 0x62, 0x07, 0x77, 0xdf, 0x2c, 0x18, 0x53, 0x61, 0x8e, 0x05, + 0x01, 0x86, 0xab, 0xab, 0xec, 0x18, 0x8c, 0x15, 0x63, 0x1f, 0xe9, 0x99, + 0xb2, 0x35, 0x77, 0xe1, 0x58, 0xf1, 0xa9, 0x4d, 0x1a, 0xb9, 0x8c, 0x30, + 0x63, 0x6f, 0x9e, 0x7d, 0x4e, 0xcf, 0xb5, 0x6c, 0xf3, 0xe4, 0xdc, 0xab, + 0xf9, 0xae, 0x58, 0xf8, 0x1d, 0x08, 0x7b, 0x73, 0x82, 0x58, 0xc8, 0x67, + 0x48, 0x1a, 0x5e, 0x3d, 0xdb, 0xac, 0x1b, 0x1b, 0xef, 0xeb, 0xa4, 0xe5, + 0x67, 0x48, 0x76, 0xd1, 0x96, 0x4f, 0x6c, 0x7d, 0x06, 0x8c, 0x02, 0x86, + 0x95, 0x83, 0xb6, 0x9b, 0x5e, 0x9a, 0xb5, 0x85, 0xc0, 0x4f, 0x13, 0x1c, + 0x32, 0xf8, 0x29, 0xdf, 0x47, 0x85, 0xdb, 0xe4, 0x37, 0xdc, 0xd8, 0x04, + 0x18, 0xdd, 0xca, 0x97, 0xdd, 0x67, 0x13, 0xbe, 0x74, 0x95, 0xdc, 0xd0, + 0xcc, 0xe6, 0xb5, 0xa5, 0x12, 0x9b, 0x23, 0x4f, 0x41, 0x8c, 0xcc, 0x95, + 0xf4, 0xb0, 0x5f, 0x2a, 0xc4, 0xbf, 0x88, 0xda, 0x55, 0xcb, 0x13, 0x93, + 0x22, 0x60, 0x51, 0x43, 0xc7, 0x9a, 0x2c, 0xfa, 0xb2, 0x59, 0xc1, 0xe6, + 0x8a, 0xa4, 0xb8, 0xfb, 0xd3, 0x31, 0x1d, 0xc7, 0x88, 0xdc, 0xbc, 0xe9, + 0xba, 0xe7, 0xdc, 0xe3, 0xdd, 0x90, 0x96, 0xb4, 0xb4, 0x0a, 0xc1, 0x07, + 0x31, 0x3f, 0xdb, 0xc5, 0x4d, 0x73, 0x58, 0x86, 0x15, 0x37, 0x07, 0x86, + 0x03, 0x17, 0x16, 0x18, 0x15, 0xb9, 0x26, 0x35, 0x8a, 0x43, 0x22, 0xae, + 0x21, 0x52, 0x05, 0x4e, 0x5c, 0x3f, 0x3e, 0xb9, 0x2a, 0x19, 0x13, 0xfd, + 0x31, 0x47, 0x6a, 0x74, 0xaa, 0xb9, 0xc6, 0x2c, 0x13, 0x8c, 0x21, 0xc4, + 0x8d, 0x00, 0xf4, 0x24, 0xf2, 0xb7, 0xd3, 0x13, 0xad, 0x29, 0x5e, 0x50, + 0x0b, 0x0e, 0x9f, 0x9a, 0xb7, 0xf6, 0x9e, 0xba, 0x12, 0x23, 0x84, 0x8c, + 0xbe, 0x2c, 0x14, 0x1e, 0xe6, 0x79, 0x15, 0x20, 0x2d, 0x32, 0x08, 0xd8, + 0x1c, 0x87, 0x1b, 0xa8, 0xc0, 0xbb, 0x85, 0xa9, 0x71, 0x30, 0x5e, 0x39, + 0x48, 0x87, 0xdc, 0x3d, 0x03, 0x29, 0x19, 0xd1, 0xd4, 0x21, 0x3a, 0x53, + 0x2d, 0x5e, 0x78, 0xff, 0x94, 0x4b, 0x91, 0xa6, 0xb5, 0xe5, 0x42, 0x56, + 0x67, 0x6a, 0x0e, 0xf3, 0x2d, 0x6a, 0x4e, 0xd7, 0x3a, 0x81, 0xb1, 0x4d, + 0x0b, 0x66, 0x5f, 0x43, 0x28, 0x7c, 0x75, 0x8b, 0x2b, 0x99, 0x24, 0xc2, + 0x5e, 0x8c, 0x22, 0xf0, 0xd5, 0xb3, 0xfc, 0x86, 0x62, 0xf3, 0xd2, 0x6c, + 0xa7, 0x48, 0x04, 0x44, 0x5d, 0x93, 0x74, 0x37, 0x16, 0x2c, 0x19, 0x12, + 0x57, 0x49, 0xef, 0xd5, 0xd6, 0x92, 0xdc, 0x51, 0xf8, 0x55, 0x3a, 0xc0, + 0x0b, 0xdf, 0x41, 0xb5, 0x01, 0x59, 0x7e, 0x85, 0x65, 0xdb, 0x44, 0xbd, + 0x04, 0x96, 0x1a, 0xd4, 0x6e, 0x22, 0x54, 0x92, 0xdb, 0xc7, 0xc5, 0x3a, + 0xdf, 0x0c, 0xf4, 0x1b, 0xdc, 0x14, 0xf6, 0x91, 0x9c, 0xbe, 0xf8, 0x8e, + 0x70, 0xd1, 0x3a, 0x0e, 0x58, 0xe6, 0xb9, 0xd3, 0xaa, 0xa2, 0x70, 0xba, + 0xdd, 0x16, 0x13, 0x19, 0xd1, 0x96, 0x78, 0x04, 0x2f, 0xd7, 0x38, 0x8c, + 0x35, 0x1f, 0xfc, 0x58, 0xa4, 0x4c, 0xa9, 0x9a, 0xae, 0x13, 0x3b, 0xc1, + 0x20, 0x4b, 0x66, 0x0f, 0x72, 0x42, 0x0a, 0x53, 0x84, 0x54, 0x71, 0x06, + 0xdb, 0x85, 0x8f, 0x40, 0xa6, 0x09, 0xf7, 0x24, 0xc4, 0x35, 0xf7, 0x1d, + 0xd4, 0x3d, 0x54, 0x75, 0xaf, 0xc4, 0x78, 0x0f, 0xce, 0xe0, 0x0c, 0x90, + 0x0f, 0xd5, 0x2e, 0x61, 0xf7, 0x58, 0xaa, 0xf0, 0xc7, 0x37, 0x5a, 0x59, + 0x1f, 0x8a, 0x03, 0x98, 0x43, 0xb7, 0x27, 0x78, 0x4e, 0x44, 0x5a, 0xb5, + 0x29, 0xf5, 0xab, 0x9e, 0xb7, 0x2a, 0xc4, 0xa3, 0x03, 0x00, 0xe3, 0x28, + 0x57, 0xc9, 0x2a, 0x98, 0xb8, 0xa1, 0x45, 0x1d, 0xfa, 0x6e, 0xb3, 0x0d, + 0x42, 0x5a, 0xb6, 0xb1, 0x0e, 0x5c, 0xbe, 0x82, 0xe2, 0x36, 0x40, 0x4b, + 0x05, 0x28, 0xd9, 0xbc, 0x27, 0xd6, 0x77, 0x00, 0xc9, 0x29, 0x6a, 0xd6, + 0x19, 0x8f, 0x8d, 0xda, 0xe1, 0xc3, 0x8b, 0x69, 0x71, 0xd0, 0xf7, 0xc8, + 0x33, 0xef, 0xe6, 0x23, 0x6b, 0xcb, 0x00, 0x56, 0x0a, 0x9b, 0x9d, 0x60, + 0x3a, 0xd3, 0xad, 0xd9, 0x5c, 0x6a, 0x7d, 0xab, 0x35, 0x71, 0x93, 0xc5, + 0xf2, 0x6a, 0x38, 0x0e, 0xfb, 0xd9, 0x9b, 0xa5, 0xda, 0x52, 0x45, 0xef, + 0x93, 0x94, 0x5b, 0x08, 0x8c, 0x07, 0xab, 0x2e, 0x99, 0x88, 0x77, 0xb5, + 0x15, 0x66, 0x7f, 0x0e, 0xfa, 0xb0, 0x29, 0xe4, 0x88, 0xd9, 0xdd, 0x22, + 0xaf, 0x7a, 0x4e, 0xb5, 0xd0, 0x62, 0x85, 0x27, 0x33, 0xf1, 0xb7, 0x34, + 0xb1, 0xe6, 0xda, 0x9f, 0x3c, 0xfe, 0xf5, 0xd4, 0xef, 0x56, 0x48, 0x93, + 0x7a, 0x54, 0xa2, 0x7f, 0x07, 0xea, 0x31, 0xb8, 0x8b, 0xca, 0xb9, 0xdb, + 0x1e, 0x2b, 0xb5, 0x16, 0xe6, 0x0e, 0xd9, 0x3f, 0x7c, 0xf0, 0xc2, 0x3e, + 0x57, 0x64, 0x60, 0x97, 0xfb, 0xdf, 0x8c, 0x3e, 0x56, 0x22, 0x92, 0x2a, + 0xb2, 0x21, 0x00, 0x0a, 0x75, 0x89, 0x68, 0xe7, 0x51, 0xa3, 0x63, 0x05, + 0xe1, 0x6f, 0x1e, 0x1e, 0x80, 0xa2, 0x4b, 0x5d, 0xb7, 0xf4, 0xb7, 0x45, + 0x85, 0x00, 0x84, 0x6e, 0xbe, 0x0b, 0x67, 0xbf, 0x21, 0x06, 0x5a, 0x56, + 0x79, 0xe9, 0x6b, 0x0e, 0x72, 0x19, 0x2d, 0x09, 0x78, 0xd5, 0x5e, 0xc2, + 0x32, 0xee, 0x29, 0xd4, 0x7a, 0x65, 0xc7, 0xfe, 0x16, 0x86, 0xd2, 0x29, + 0x71, 0xe5, 0x91, 0x0e, 0x3e, 0x86, 0xd5, 0x00, 0xc4, 0xfc, 0xd9, 0xae, + 0xd3, 0x7c, 0x13, 0xfd, 0x62, 0xce, 0x0c, 0xb2, 0xe5, 0x1f, 0x6d, 0xed, + 0x55, 0x6f, 0xc1, 0xaa, 0xa1, 0x74, 0x59, 0x46, 0x83, 0xd5, 0x5d, 0x71, + 0x17, 0x13, 0x1d, 0x0b, 0x25, 0xfb, 0x0a, 0xcd, 0x67, 0xfe, 0x57, 0x93, + 0xc2, 0x71, 0x55, 0x6c, 0x68, 0xfa, 0x40, 0xdb, 0xdd, 0xce, 0xd5, 0x5c, + 0xce, 0x0a, 0x1d, 0xfa, 0x19, 0x30, 0xe2, 0x2b, 0x63, 0x98, 0x16, 0x2c, + 0x67, 0x69, 0x55, 0xe5, 0xc1, 0x6c, 0x6e, 0xb7, 0x92, 0x6a, 0xbb, 0x10, + 0xd3, 0x13, 0x2e, 0x73, 0x91, 0x74, 0xcb, 0x9f, 0x5c, 0x7f, 0x5c, 0x48, + 0x58, 0x36, 0x13, 0x47, 0xf7, 0x49, 0xae, 0x90, 0x15, 0x53, 0xb5, 0xe6, + 0x37, 0xfb, 0x81, 0x47, 0xb4, 0x69, 0x84, 0xca, 0x95, 0xab, 0x19, 0x2a, + 0x28, 0xc2, 0x8a, 0xf1, 0xcd, 0xf9, 0x3e, 0xd3, 0xaf, 0xe1, 0x75, 0xf7, + 0x94, 0x74, 0x1c, 0xf5, 0x32, 0xcf, 0x70, 0xbd, 0x69, 0xcc, 0xa8, 0x3c, + 0xca, 0x59, 0x53, 0xfa, 0xcb, 0xe7, 0xb6, 0x36, 0x70, 0xea, 0xe2, 0x84, + 0xfa, 0x5e, 0xbd, 0xd7, 0x59, 0x3d, 0x21, 0xc6, 0x9f, 0x5c, 0x1f, 0xa6, + 0xa9, 0xf1, 0xd3, 0x26, 0x9e, 0xff, 0xbc, 0x81, 0xfe, 0xbe, 0xee, 0x64, + 0xd9, 0x63, 0x94, 0x4b, 0x15, 0xd8, 0x95, 0xaa, 0xec, 0x10, 0xc9, 0xe2, + 0xe1, 0x05, 0x37, 0x64, 0xc4, 0xb0, 0x2e, 0xa5, 0x0e, 0x4c, 0x2d, 0x03, + 0x53, 0xf1, 0x93, 0x77, 0x9d, 0x46, 0x14, 0x67, 0x48, 0x5f, 0xad, 0x1b, + 0xdc, 0xb9, 0x74, 0xa2, 0x6c, 0xfc, 0xd2, 0xa0, 0x1f, 0x43, 0x89, 0x15, + 0xc5, 0x0c, 0xb0, 0x9e, 0x1e, 0xc2, 0xd6, 0x44, 0xd9, 0x6e, 0xfc, 0xb4, + 0x9c, 0x95, 0x90, 0xcd, 0xc3, 0x17, 0x1c, 0x6a, 0xce, 0x03, 0x56, 0x9f, + 0xe7, 0xcd, 0x7e, 0xe7, 0xa2, 0x0c, 0x2b, 0x0d, 0x59, 0xb0, 0xc9, 0x4c, + 0x6e, 0x33, 0x6d, 0x43, 0xc4, 0x3a, 0x10, 0x24, 0x03, 0x3e, 0x09, 0xb6, + 0x86, 0x13, 0xba, 0x18, 0x19, 0xd3, 0xff, 0xeb, 0xa5, 0x25, 0x8f, 0x6f, + 0xc8, 0xe6, 0x96, 0xa4, 0xd2, 0x66, 0x40, 0x81, 0x79, 0xe8, 0x39, 0x18, + 0x41, 0x02, 0x66, 0x5c, 0x30, 0x5f, 0x58, 0x9d, 0x35, 0x16, 0xc6, 0x96, + 0xa8, 0x68, 0xbc, 0x09, 0x83, 0x17, 0x2c, 0x5f, 0x5e, 0xd0, 0x1d, 0xb0, + 0x48, 0x5e, 0xcf, 0x91, 0x16, 0x4d, 0xa0, 0xba, 0xbc, 0x61, 0xa8, 0x3f, + 0x30, 0x09, 0xbb, 0xa3, 0x12, 0xcd, 0xdc, 0x29, 0xf7, 0xb0, 0xad, 0x05, + 0x17, 0xd6, 0xd3, 0x16, 0xfb, 0xe5, 0x99, 0xf4, 0x71, 0x62, 0xa3, 0x45, + 0x45, 0xc7, 0x9b, 0xaa, 0x45, 0xd3, 0x35, 0xfe, 0xfb, 0x63, 0xaf, 0xe7, + 0x85, 0x31, 0xc9, 0x66, 0x26, 0xa9, 0xda, 0x8c, 0xc6, 0xf6, 0xd5, 0xdf, + 0xb1, 0xa9, 0xf1, 0xb6, 0x3d, 0x92, 0xae, 0x4d, 0xbc, 0x74, 0x7d, 0x76, + 0x5a, 0x59, 0x8c, 0x87, 0xff, 0x95, 0x2f, 0x67, 0x37, 0x30, 0x1a, 0xc1, + 0x23, 0x2e, 0x0c, 0xaa, 0x80, 0x1c, 0xf3, 0xa3, 0x74, 0x94, 0xb2, 0xda, + 0x1a, 0xb8, 0x46, 0xec, 0x30, 0x76, 0xf4, 0xdf, 0xfb, 0x00, 0xb3, 0x6f, + 0x86, 0xc1, 0xc5, 0x3a, 0x5d, 0x11, 0x14, 0x87, 0xeb, 0x30, 0xd8, 0x33, + 0x18, 0x00, 0x01, 0x76, 0x43, 0x82, 0xcd, 0x1c, 0x36, 0x54, 0xd2, 0x64, + 0x5b, 0xfb, 0x93, 0xca, 0x20, 0x1d, 0xa3, 0x20, 0x99, 0xc3, 0x8e, 0x5c, + 0x82, 0xfc, 0x56, 0x07, 0x41, 0x4b, 0x4f, 0x54, 0xc7, 0xb5, 0xe8, 0x6d, + 0x7e, 0xd8, 0x8a, 0x56, 0xb4, 0x76, 0x1e, 0xd3, 0x82, 0x97, 0xdd, 0x2b, + 0xd9, 0x80, 0xb7, 0xb6, 0xeb, 0x3d, 0xe5, 0xe0, 0x20, 0x27, 0x8c, 0xf0, + 0xd6, 0x14, 0xc7, 0xcd, 0x79, 0xbc, 0xa0, 0x21, 0x85, 0xc3, 0x02, 0xae, + 0x73, 0xc4, 0x0a, 0x39, 0x1a, 0x98, 0x61, 0xc3, 0x86, 0xd8, 0x97, 0x67, + 0x87, 0xe9, 0x56, 0x0b, 0x61, 0xa6, 0x7e, 0x07, 0xfb, 0x0a, 0x8b, 0xd1, + 0x90, 0xbd, 0x39, 0x22, 0xdb, 0xc2, 0x7f, 0xaa, 0x79, 0xb7, 0x39, 0x09, + 0xc1, 0x69, 0xdb, 0xe2, 0x7f, 0xec, 0xde, 0x80, 0x7a, 0x6c, 0xde, 0x76, + 0xa4, 0xe8, 0xe0, 0x8d, 0x71, 0xfa, 0x62, 0xf0, 0x2e, 0x7b, 0xf4, 0xce, + 0x65, 0x18, 0x42, 0xde, 0x92, 0x1b, 0xdc, 0xc9, 0xa7, 0x8d, 0xa5, 0x91, + 0x0f, 0xa5, 0x1b, 0x89, 0xcf, 0x29, 0x10, 0x1d, 0x94, 0x78, 0x1b, 0xea, + 0x79, 0x35, 0x62, 0xd4, 0x29, 0xe6, 0x59, 0x8c, 0xc1, 0xd2, 0xf3, 0x32, + 0x71, 0x09, 0xce, 0x51, 0xd7, 0x14, 0x29, 0x92, 0xbf, 0xdf, 0x9a, 0x69, + 0xda, 0x61, 0x03, 0x0f, 0xa2, 0x0a, 0xab, 0x57, 0x1c, 0xca, 0xab, 0x42, + 0x63, 0x63, 0x1e, 0x35, 0x5d, 0x8d, 0xba, 0x6f, 0x4b, 0x6b, 0x5e, 0x7c, + 0xc0, 0x1e, 0xb7, 0xf4, 0x65, 0xbd, 0x13, 0x1c, 0xf2, 0xa9, 0x73, 0x38, + 0xc3, 0x47, 0xc9, 0x32, 0xf0, 0x30, 0x57, 0x05, 0x42, 0x52, 0xac, 0x72, + 0xee, 0x9f, 0x4e, 0x21, 0xbf, 0x38, 0x19, 0x6d, 0x48, 0xec, 0x97, 0xcb, + 0x70, 0x9e, 0xee, 0xb3, 0xa1, 0xaa, 0xa6, 0x7e, 0xe9, 0x16, 0xdf, 0xcd, + 0x1c, 0x56, 0xcf, 0xf0, 0x9f, 0x4d, 0xd1, 0x8c, 0x14, 0x50, 0x5d, 0x23, + 0x96, 0xe0, 0x1f, 0x61, 0x79, 0xbf, 0x44, 0xfd, 0xa2, 0x31, 0xf7, 0x4c, + 0x0c, 0x8d, 0x8c, 0x1b, 0xbf, 0x8d, 0x45, 0xbf, 0x0b, 0xd8, 0xfb, 0x6f, + 0xff, 0x15, 0xc0, 0x44, 0x7c, 0xb9, 0xb8, 0xf9, 0xef, 0x0d, 0x79, 0x11, + 0x3b, 0x79, 0xd2, 0x52, 0x89, 0x5a, 0xcd, 0x0f, 0x10, 0x92, 0x42, 0xfe, + 0xcf, 0x0a, 0x11, 0x8a, 0x8a, 0xda, 0xee, 0xc8, 0x6b, 0xd9, 0xab, 0xec, + 0xb4, 0x25, 0x6f, 0x8d, 0x68, 0x26, 0xe8, 0xdd, 0xf5, 0xa4, 0xe8, 0x65, + 0x37, 0x03, 0xb0, 0xad, 0x73, 0x3b, 0x4d, 0x74, 0x57, 0x7f, 0x0f, 0x6c, + 0xb0, 0x5d, 0x59, 0x80, 0x13, 0xa1, 0x6c, 0xb0, 0xed, 0x26, 0xec, 0x79, + 0x50, 0x5f, 0x5c, 0xb7, 0xa6, 0xae, 0xe8, 0x0a, 0x6d, 0x55, 0x9a, 0x7f, + 0x59, 0x23, 0xa3, 0x7e, 0x84, 0x7b, 0x3b, 0xfc, 0xde, 0xe1, 0xd9, 0x7c, + 0xd6, 0x87, 0xb3, 0x0e, 0xdb, 0xc1, 0x8c, 0x5e, 0x77, 0xb7, 0x23, 0xd7, + 0x14, 0xd4, 0x23, 0xb4, 0xac, 0x45, 0xbf, 0xfe, 0x40, 0x20, 0x4d, 0x91, + 0x20, 0x94, 0xbd, 0x58, 0xb1, 0x99, 0x69, 0xaf, 0x31, 0x68, 0xbd, 0x61, + 0x5e, 0x87, 0x81, 0x54, 0x4e, 0x2d, 0x03, 0xc2, 0xe2, 0xcd, 0xdc, 0x59, + 0xe5, 0x35, 0xcf, 0xb8, 0xfc, 0x65, 0xed, 0x46, 0xb3, 0x92, 0xe7, 0xf8, + 0x3a, 0x32, 0xaa, 0x0e, 0x5a, 0x82, 0x58, 0x4e, 0x77, 0xd8, 0x33, 0xc9, + 0xb0, 0x3e, 0xad, 0xa5, 0x92, 0xe9, 0xa9, 0x8c, 0x00, 0x72, 0x8f, 0xdc, + 0x77, 0x9d, 0x5c, 0x97, 0xd6, 0x58, 0x20, 0x1e, 0xf4, 0x55, 0x2d, 0xc0, + 0x30, 0xf0, 0x66, 0xda, 0x2d, 0x11, 0xac, 0xd4, 0x2d, 0xd5, 0x25, 0x42, + 0x1d, 0xce, 0x49, 0xb5, 0x95, 0x79, 0x9b, 0x6c, 0x65, 0xe0, 0x8a, 0xc5, + 0x9f, 0x75, 0xe3, 0xe6, 0xf8, 0xa6, 0x88, 0xd6, 0x93, 0x70, 0x4f, 0x89, + 0x94, 0x74, 0xbd, 0xef, 0xc2, 0x1a, 0x55, 0x74, 0x37, 0x44, 0x85, 0x1e, + 0xa9, 0xbb, 0x3f, 0x15, 0xc7, 0x84, 0x80, 0xa5, 0xab, 0xc3, 0x91, 0x8e, + 0xd6, 0x32, 0x46, 0x0d, 0xfa, 0xd1, 0x19, 0xd1, 0xfc, 0x02, 0xe2, 0x20, + 0xa6, 0xa9, 0xf7, 0xf4, 0xcc, 0x5b, 0x54, 0x4f, 0x4a, 0x73, 0x35, 0xda, + 0xf0, 0x31, 0x81, 0x1a, 0x82, 0xe7, 0xd4, 0xc8, 0xb4, 0x1d, 0x70, 0xa9, + 0x5d, 0x67, 0xb9, 0x7d, 0x4b, 0xcd, 0xa4, 0x81, 0xf9, 0xb2, 0x38, 0x07, + 0x16, 0xd5, 0x28, 0x82, 0xb9, 0x76, 0x5b, 0xa1, 0x09, 0x7a, 0xe7, 0x2a, + 0xcf, 0xc0, 0x3d, 0x2a, 0x42, 0x9a, 0xf3, 0xc8, 0x64, 0x15, 0x7c, 0x94, + 0xd0, 0x97, 0xee, 0x34, 0xb6, 0xf0, 0xb2, 0xba, 0x7e, 0xb2, 0xbb, 0x4e, + 0xbf, 0x88, 0xd0, 0x6b, 0xc5, 0x9c, 0xb9, 0xf2, 0x7d, 0xbf, 0x5d, 0x87, + 0xbc, 0x36, 0x4a, 0xd1, 0x1b, 0x6f, 0x40, 0x09, 0xba, 0x26, 0x51, 0xd6, + 0xc0, 0xaf, 0x27, 0xce, 0x27, 0x8d, 0x93, 0xa8, 0x6c, 0x91, 0xe7, 0x91, + 0x42, 0xc0, 0x68, 0x36, 0x5b, 0xd5, 0x56, 0x4c, 0xe2, 0x77, 0xc3, 0xac, + 0x56, 0xe3, 0x1c, 0xc2, 0xf9, 0x78, 0x02, 0x39, 0x7d, 0xed, 0x18, 0x2a, + 0x01, 0x48, 0xe6, 0xf6, 0x7e, 0x34, 0x50, 0xf4, 0x57, 0x56, 0x93, 0xdb, + 0x85, 0x1b, 0x1e, 0x1a, 0x6f, 0x3e, 0x07, 0x3c, 0xad, 0x3f, 0x8d, 0x75, + 0x53, 0xc3, 0x20, 0x72, 0x93, 0x28, 0xd2, 0x86, 0xc8, 0xa5, 0x90, 0xf2, + 0x5f, 0x13, 0xd5, 0xa5, 0xbe, 0x88, 0x9e, 0x9a, 0x57, 0x2c, 0x53, 0x3f, + 0x11, 0x25, 0x00, 0x00, 0x4a, 0x16, 0x8d, 0xd3, 0x3f, 0x2d, 0x3d, 0x88, + 0xbb, 0x4c, 0x4f, 0x9a, 0xb9, 0x97, 0x5f, 0xed, 0x71, 0xa9, 0x68, 0xd9, + 0x4a, 0x14, 0x24, 0xc7, 0xbe, 0xff, 0x85, 0x57, 0xa3, 0x21, 0xe3, 0x21, + 0x79, 0x1f, 0xd0, 0xbb, 0xb7, 0x73, 0xde, 0x60, 0x02, 0x4b, 0x8f, 0x7d, + 0xb3, 0xb3, 0x8a, 0xda, 0x4c, 0xf4, 0xb8, 0xf1, 0x31, 0xff, 0x32, 0x7b, + 0xd8, 0xfa, 0xb1, 0xcb, 0xb4, 0x58, 0xf5, 0xc8, 0x64, 0xdf, 0xfe, 0x3d, + 0x89, 0x52, 0x5c, 0x52, 0x95, 0xf3, 0xba, 0x0d, 0x1d, 0x2c, 0xc4, 0xf7, + 0x3c, 0x3b, 0x6f, 0x8e, 0xc7, 0xab, 0xad, 0x3d, 0x3d, 0x95, 0x9b, 0xc7, + 0x71, 0x36, 0xae, 0x08, 0xc3, 0x08, 0x79, 0xfa, 0x24, 0xee, 0xd9, 0xf9, + 0x63, 0xc7, 0xd9, 0x16, 0x19, 0x8e, 0x0d, 0xaf, 0x52, 0x87, 0x86, 0x7d, + 0xec, 0xe5, 0xea, 0x5a, 0xda, 0x86, 0x9d, 0x0e, 0x50, 0x53, 0x8c, 0x24, + 0xa8, 0x69, 0xc4, 0xf3, 0x85, 0x7b, 0x34, 0x67, 0x19, 0x35, 0xec, 0xd4, + 0xd4, 0x50, 0xe0, 0xe6, 0xe9, 0x29, 0x5b, 0x92, 0xee, 0xba, 0xa9, 0xef, + 0xf6, 0x35, 0x23, 0x8b, 0xdb, 0x48, 0x32, 0x25, 0x41, 0xf3, 0x55, 0x12, + 0x33, 0xc3, 0x6c, 0xed, 0x32, 0xe1, 0x64, 0x7a, 0x8d, 0xa2, 0x19, 0x5a, + 0x26, 0xf2, 0x83, 0xf1, 0xe4, 0x27, 0xdb, 0x67, 0xc3, 0x89, 0x37, 0xea, + 0x78, 0x19, 0xc6, 0xa3, 0x82, 0x84, 0x1c, 0xf3, 0x2b, 0xbe, 0xde, 0xba, + 0xe7, 0x60, 0x2e, 0xf5, 0x4e, 0xb6, 0x73, 0x29, 0xac, 0xc7, 0x55, 0xab, + 0x21, 0xe9, 0x95, 0x78, 0xd5, 0x8e, 0x27, 0xdc, 0x92, 0x5f, 0xc0, 0xcb, + 0xee, 0x66, 0x09, 0x0a, 0xfc, 0x94, 0x43, 0x44, 0x50, 0x35, 0x57, 0xf8, + 0x08, 0xf9, 0x97, 0xa2, 0x0e, 0xde, 0x81, 0xe1, 0xd1, 0xa0, 0x41, 0xfe, + 0xe6, 0x08, 0x6c, 0x98, 0x8c, 0x81, 0x46, 0x0e, 0xf9, 0x9a, 0x54, 0xfe, + 0xc3, 0x91, 0xe3, 0xd4, 0x46, 0xca, 0x52, 0xa2, 0x73, 0x9e, 0x4d, 0xa7, + 0xfd, 0xa1, 0x8e, 0x43, 0x28, 0xf5, 0xa3, 0xa2, 0x62, 0x20, 0x53, 0x62, + 0x05, 0x49, 0xba, 0x06, 0xe2, 0xeb, 0xba, 0xfb, 0x8e, 0xa0, 0x22, 0xc7, + 0xf9, 0xcc, 0x7f, 0x8b, 0xa8, 0x5d, 0x55, 0xd2, 0x24, 0xff, 0xdd, 0x2c, + 0xc1, 0xd0, 0x3d, 0xe4, 0x79, 0xea, 0xba, 0x62, 0xe5, 0xa2, 0x62, 0xf4, + 0x1f, 0xec, 0xb0, 0x07, 0xf2, 0x0d, 0x32, 0x84, 0x86, 0x81, 0x3d, 0x95, + 0xc1, 0x64, 0xfe, 0x9a, 0x3d, 0x8f, 0x4b, 0x6d, 0xfb, 0x0d, 0x42, 0xcf, + 0xbf, 0xdb, 0x51, 0xb2, 0x16, 0xa2, 0x35, 0xaa, 0xe7, 0x31, 0x54, 0xc2, + 0x87, 0xc6, 0xa5, 0x30, 0x71, 0x64, 0x65, 0xff, 0x41, 0x20, 0xb0, 0x83, + 0xdb, 0xb7, 0x95, 0xce, 0xd7, 0xcc, 0x7a, 0x77, 0xad, 0xb8, 0xb7, 0x4c, + 0xfc, 0x11, 0x05, 0x2b, 0xc4, 0xd4, 0xb6, 0x8b, 0xae, 0x13, 0xa5, 0x40, + 0x18, 0x6e, 0x0d, 0xe3, 0xc6, 0xb0, 0x81, 0x46, 0x46, 0x7e, 0x52, 0x0b, + 0x85, 0x4d, 0x98, 0xd9, 0x42, 0xdf, 0xde, 0x45, 0xc1, 0x5a, 0x33, 0x12, + 0x46, 0x26, 0xb3, 0x6f, 0xf2, 0x8b, 0x37, 0x6b, 0xfd, 0x08, 0xf4, 0x46, + 0x86, 0x89, 0x63, 0x63, 0x21, 0xe5, 0xa9, 0xb7, 0xd0, 0x09, 0x17, 0x52, + 0xee, 0xea, 0xdf, 0x97, 0xb7, 0x73, 0x2e, 0x54, 0x2c, 0x7b, 0x70, 0xd3, + 0xda, 0x26, 0x57, 0x1f, 0xb0, 0x19, 0xd9, 0x91, 0x18, 0x69, 0x75, 0x42, + 0x63, 0xcf, 0x6c, 0x8c, 0x98, 0x5e, 0x17, 0x99, 0x7e, 0x1d, 0xdc, 0x67, + 0x6d, 0x99, 0xd9, 0x02, 0x6e, 0x73, 0x90, 0x5a, 0x4f, 0x0a, 0xb4, 0x48, + 0xfb, 0xc5, 0xbd, 0xd2, 0x10, 0x05, 0xa6, 0x12, 0x68, 0x36, 0x28, 0x51, + 0x60, 0x1c, 0xa1, 0xe9, 0x90, 0x54, 0xa5, 0x53, 0xc3, 0x48, 0x9e, 0xd8, + 0x42, 0x52, 0x85, 0x0e, 0xff, 0xfe, 0xbf, 0xad, 0x3a, 0xa4, 0x57, 0x09, + 0x13, 0x38, 0x64, 0x15, 0x7c, 0xfd, 0xed, 0x91, 0x76, 0x44, 0x20, 0x84, + 0xd9, 0x90, 0xab, 0xfe, 0xfd, 0xd6, 0xab, 0xf1, 0xb3, 0x25, 0x21, 0x3d, + 0x97, 0x72, 0xb2, 0x95, 0xc5, 0x22, 0x80, 0xd9, 0x4a, 0x49, 0x9d, 0x99, + 0xc2, 0x4a, 0x9a, 0x59, 0xb3, 0x71, 0x75, 0x5b, 0xf9, 0x89, 0x7a, 0xdd, + 0xa9, 0xb3, 0xc3, 0xeb, 0x42, 0x91, 0xe2, 0x97, 0x30, 0x40, 0x48, 0x68, + 0x19, 0x3b, 0xf5, 0x7b, 0x4e, 0x33, 0x4b, 0x0c, 0xf3, 0xed, 0xda, 0x76, + 0x3f, 0xb0, 0x4b, 0x53, 0x85, 0x04, 0x33, 0x07, 0x53, 0xd8, 0x55, 0xa2, + 0xfb, 0x30, 0x2c, 0x66, 0xbd, 0x21, 0xf8, 0xfa, 0x20, 0x14, 0x9a, 0x0d, + 0x7f, 0xc9, 0x2f, 0x5b, 0x34, 0x29, 0x09, 0x16, 0xb5, 0x0a, 0x8d, 0xdf, + 0xa2, 0x84, 0x9a, 0xae, 0xe6, 0xa0, 0x50, 0x80, 0x31, 0x04, 0xd3, 0x0c, + 0x8f, 0xd1, 0x8a, 0xfd, 0xb4, 0xa5, 0xae, 0xf5, 0x3c, 0x62, 0xae, 0x45, + 0x70, 0xbb, 0x54, 0x62, 0xc8, 0x50, 0x71, 0x42, 0x85, 0xf6, 0x6f, 0xa0, + 0xf0, 0x10, 0x8a, 0x09, 0xbd, 0x71, 0x78, 0xa6, 0x5e, 0xe4, 0x03, 0x8f, + 0x3b, 0xd0, 0x5c, 0x37, 0x55, 0x1a, 0xc8, 0x57, 0x26, 0x62, 0x6c, 0xc4, + 0x67, 0x71, 0x9d, 0x97, 0xc0, 0xea, 0x35, 0x3e, 0x12, 0xd0, 0x2b, 0xc2, + 0x8f, 0x9e, 0xa6, 0x41, 0x48, 0x33, 0x83, 0x38, 0x37, 0x7e, 0xd4, 0xe3, + 0xee, 0x94, 0x8b, 0x81, 0xa4, 0x60, 0xdd, 0xdd, 0xc1, 0x8a, 0x7b, 0xda, + 0xa8, 0x46, 0xb8, 0x42, 0x3a, 0x25, 0xd6, 0x81, 0x89, 0x29, 0x21, 0xc2, + 0x0c, 0x5b, 0xfd, 0x3e, 0x8c, 0x65, 0x91, 0x52, 0xb3, 0x74, 0x1f, 0xd1, + 0x49, 0x7e, 0x1d, 0x59, 0x58, 0x96, 0xb5, 0xee, 0x32, 0xa4, 0xa8, 0x07, + 0x7c, 0xd1, 0x5b, 0x4b, 0xf8, 0x43, 0x5a, 0xa5, 0xcc, 0x60, 0xcc, 0x08, + 0x6a, 0x3c, 0x41, 0x66, 0x99, 0xe3, 0xa8, 0xe0, 0xb8, 0x87, 0xfc, 0x92, + 0xc0, 0x79, 0xc5, 0x3f, 0xd6, 0xc6, 0x8c, 0x01, 0xf4, 0xa5, 0x05, 0xad, + 0x51, 0xed, 0x04, 0xd7, 0x55, 0xc0, 0x73, 0x05, 0x0e, 0x73, 0xe5, 0x39, + 0x45, 0x5b, 0x95, 0x4a, 0x34, 0x07, 0x99, 0xdf, 0x4c, 0x35, 0xf5, 0x0c, + 0x27, 0x6d, 0xd1, 0x45, 0xf1, 0xfd, 0x24, 0xb7, 0xfe, 0xea, 0x11, 0x5d, + 0xa2, 0xc5, 0xa6, 0x81, 0x37, 0x1d, 0xc2, 0x31, 0x31, 0xfc, 0xe0, 0xf4, + 0xd7, 0xe9, 0x98, 0x8b, 0xe3, 0x70, 0x51, 0x62, 0xc8, 0x61, 0x6d, 0xec, + 0x75, 0x56, 0x71, 0xae, 0x88, 0xe0, 0x80, 0xf5, 0xb7, 0x85, 0x10, 0xb7, + 0x3d, 0x16, 0x78, 0x5f, 0x72, 0xab, 0x8f, 0x63, 0xc6, 0xd5, 0xa8, 0xc9, + 0x9c, 0xef, 0x8d, 0x9a, 0xc5, 0x4f, 0x63, 0xad, 0xc0, 0xf3, 0x1f, 0x69, + 0x0e, 0xce, 0x29, 0x92, 0xc1, 0x3b, 0xb0, 0xc5, 0xed, 0x0a, 0x7b, 0x92, + 0xd0, 0x4c, 0x9c, 0x82, 0xb0, 0x51, 0xf6, 0x33, 0x61, 0x3b, 0x76, 0x48, + 0x38, 0xf4, 0x7c, 0xaa, 0x52, 0x87, 0x15, 0x1a, 0xbe, 0xb8, 0xdc, 0x9b, + 0x16, 0xd2, 0x07, 0xf7, 0xf9, 0x74, 0xe0, 0xaf, 0x0e, 0x29, 0x05, 0xec, + 0x6c, 0x0e, 0x3b, 0xa7, 0xe7, 0xa4, 0xfc, 0xa4, 0xef, 0x57, 0x16, 0x7f, + 0x13, 0xbd, 0x8c, 0x42, 0x02, 0x55, 0x70, 0x56, 0xa5, 0xa9, 0x01, 0x29, + 0x12, 0x7d, 0x80, 0x46, 0x18, 0x8e, 0x39, 0x3f, 0x44, 0x55, 0xec, 0xef, + 0x60, 0x58, 0x7d, 0xce, 0x64, 0x8e, 0x9c, 0xea, 0xe4, 0x73, 0xd1, 0x48, + 0x9c, 0x3f, 0x92, 0xa0, 0x9a, 0x76, 0xa5, 0x5a, 0x13, 0x1f, 0x10, 0xb9, + 0xb7, 0xb1, 0xde, 0x49, 0x22, 0x58, 0xf4, 0x43, 0x5f, 0x03, 0x43, 0xc3, + 0x6c, 0xbf, 0x82, 0xaf, 0x88, 0x39, 0xfd, 0xb2, 0x28, 0x9b, 0x47, 0x3f, + 0x83, 0x3d, 0xd9, 0x7c, 0xf0, 0xc9, 0xc5, 0xa2, 0xb4, 0xd6, 0x0d, 0x59, + 0x51, 0x27, 0x60, 0x10, 0x5e, 0xbb, 0x18, 0xa6, 0x42, 0x4a, 0x9d, 0xc4, + 0x16, 0x0e, 0xb6, 0x57, 0x23, 0x03, 0x24, 0x27, 0xdc, 0x20, 0x56, 0x30, + 0x8b, 0x0f, 0xb6, 0xb7, 0x73, 0xf5, 0x36, 0x3e, 0xf6, 0x7a, 0x71, 0xa5, + 0x57, 0xcc, 0x6d, 0xc6, 0xf3, 0xdc, 0x35, 0xfb, 0x95, 0xf7, 0xa7, 0xd7, + 0x56, 0x38, 0xd4, 0x15, 0xe2, 0xd5, 0x6f, 0x70, 0x30, 0xc8, 0x7d, 0x8a, + 0x87, 0xe6, 0xd1, 0xe0, 0x50, 0x62, 0xde, 0xfa, 0x29, 0x40, 0x97, 0xa0, + 0x54, 0x63, 0x31, 0xd3, 0x08, 0x87, 0x0a, 0xdc, 0x6e, 0x5e, 0xab, 0x8d, + 0x16, 0xaf, 0x6e, 0x8b, 0x1a, 0x77, 0xf6, 0xd4, 0xe0, 0xbf, 0x59, 0xab, + 0xc7, 0xb0, 0x45, 0x18, 0xaa, 0xe6, 0x65, 0x6f, 0x7d, 0x13, 0xb2, 0xbf, + 0xb3, 0x66, 0x72, 0xfa, 0xfd, 0xee, 0xad, 0x07, 0x56, 0x51, 0x6a, 0xe2, + 0xff, 0xb2, 0xaf, 0x4d, 0xd1, 0xf2, 0x77, 0x35, 0x5e, 0x90, 0xcd, 0xe7, + 0xa8, 0x32, 0x4d, 0x9f, 0xbd, 0xa8, 0xce, 0xab, 0xf1, 0x49, 0x98, 0xb5, + 0x23, 0x5c, 0x62, 0x2d, 0x43, 0x31, 0x80, 0x87, 0xc2, 0xa8, 0xf5, 0xb9, + 0xb6, 0xae, 0x7f, 0x37, 0x13, 0xb8, 0x6b, 0x73, 0xf3, 0x56, 0x38, 0xa7, + 0x9b, 0x97, 0x69, 0x37, 0x00, 0xdc, 0xff, 0xfe, 0x58, 0xc9, 0x12, 0x47, + 0x75, 0x98, 0x1f, 0xad, 0xd8, 0xb5, 0xc8, 0x47, 0x4f, 0xd0, 0x72, 0x63, + 0x54, 0x25, 0x6c, 0x88, 0xc9, 0x9f, 0x3c, 0x82, 0xe0, 0xdd, 0x4c, 0xff, + 0x8e, 0xaf, 0x8f, 0x8e, 0xea, 0x84, 0x3f, 0x73, 0xdd, 0x9e, 0x18, 0x73, + 0x47, 0x70, 0xc7, 0xc7, 0x99, 0x65, 0xcf, 0xf3, 0xb6, 0x24, 0xed, 0x97, + 0x8f, 0xcd, 0x93, 0x1e, 0xff, 0x6e, 0x9c, 0xf1, 0x30, 0x14, 0x1a, 0x27, + 0x59, 0x6a, 0x0e, 0xf3, 0xe4, 0xfa, 0x1d, 0x65, 0xb5, 0x53, 0xe4, 0xab, + 0xb1, 0x3e, 0xe1, 0x91, 0xf4, 0x6d, 0x99, 0xca, 0x7d, 0x03, 0x08, 0x50, + 0xea, 0xa9, 0x39, 0x7f, 0x6d, 0xe7, 0x43, 0xfb, 0x64, 0xcc, 0x4b, 0x9e, + 0xa0, 0x26, 0xe4, 0x0e, 0xff, 0xb7, 0x11, 0x0a, 0x29, 0x50, 0x90, 0xd7, + 0x4d, 0x62, 0x9a, 0x4a, 0x23, 0xb7, 0xd3, 0x53, 0xde, 0x3a, 0xd1, 0xba, + 0xd3, 0x10, 0x59, 0xc6, 0xc5, 0x5e, 0xac, 0xf9, 0x61, 0x74, 0x54, 0xf4, + 0x27, 0x9f, 0x9a, 0x61, 0x13, 0xdc, 0xe5, 0x96, 0xe3, 0x95, 0x0d, 0xcc, + 0xbd, 0x81, 0x74, 0x79, 0x73, 0xef, 0x2e, 0x0b, 0x0f, 0x91, 0x65, 0x3c, + 0x26, 0x7c, 0x47, 0x10, 0x31, 0x0b, 0xfb, 0x41, 0x0c, 0xc2, 0xa8, 0xc4, + 0x0e, 0xbd, 0x0a, 0x8c, 0xa4, 0x80, 0x45, 0x57, 0x62, 0x0b, 0x4d, 0x44, + 0x5e, 0x59, 0x77, 0xfd, 0x3d, 0xf3, 0xd7, 0x92, 0x49, 0xc1, 0xcb, 0x8a, + 0x54, 0x56, 0x3b, 0xde, 0xcf, 0x16, 0x9a, 0x65, 0xbe, 0xac, 0x64, 0xe1, + 0xd4, 0xd4, 0x1e, 0xac, 0x6b, 0x4a, 0xad, 0xc4, 0x33, 0xac, 0xcb, 0x83, + 0xf4, 0x4d, 0xe8, 0xb6, 0xd7, 0x23, 0xd7, 0x71, 0x25, 0xa2, 0x25, 0x3d, + 0x7e, 0xf0, 0x3b, 0x7f, 0x61, 0x11, 0x56, 0xd4, 0x83, 0xc8, 0xc0, 0x29, + 0x38, 0x10, 0x73, 0xad, 0x6a, 0xb7, 0xb9, 0xd2, 0x2e, 0x9f, 0xae, 0x16, + 0x5e, 0xa6, 0x13, 0x1c, 0xc2, 0x17, 0x73, 0x43, 0x03, 0xdd, 0xa6, 0xaf, + 0x9a, 0x17, 0x31, 0xb8, 0x86, 0x97, 0xc2, 0xd6, 0xe6, 0xed, 0xd4, 0xe1, + 0x7d, 0xb9, 0xa6, 0x96, 0xc1, 0x4b, 0xcb, 0x11, 0x1e, 0xe1, 0xe0, 0xd2, + 0x28, 0x69, 0x68, 0x3b, 0x21, 0x17, 0x63, 0x0c, 0xc0, 0x49, 0x30, 0x22, + 0x3a, 0x59, 0x72, 0xe6, 0x47, 0xb4, 0xdc, 0xa8, 0x29, 0x1c, 0x89, 0xa6, + 0x3a, 0x77, 0x99, 0xea, 0x46, 0xce, 0x38, 0xda, 0x31, 0x88, 0xad, 0xe7, + 0x26, 0xce, 0xc6, 0x56, 0x04, 0x30, 0xfa, 0x01, 0xac, 0xbb, 0xe2, 0xb8, + 0x23, 0xe4, 0x9d, 0x4f, 0x77, 0x02, 0x00, 0x28, 0xf1, 0xe0, 0x19, 0x3f, + 0x22, 0x4f, 0x22, 0x69, 0x87, 0xc0, 0x4e, 0x26, 0x33, 0xfe, 0x6c, 0x70, + 0x56, 0x3b, 0x60, 0x5f, 0xfb, 0xf8, 0x43, 0xcf, 0x3f, 0xb9, 0xcb, 0x80, + 0x22, 0xbb, 0x0a, 0xa8, 0x1c, 0x3e, 0x7e, 0x4d, 0x42, 0x60, 0x5c, 0x8e, + 0xfa, 0x42, 0xb3, 0x95, 0xe7, 0x92, 0x6b, 0xec, 0x7a, 0x95, 0x88, 0x98, + 0xe3, 0xf9, 0x0d, 0xe5, 0x08, 0xf1, 0x26, 0x96, 0x2a, 0x81, 0x2b, 0x7c, + 0x0d, 0x12, 0xa0, 0x7f, 0x7b, 0x39, 0xf6, 0xcc, 0x1b, 0x2d, 0x2c, 0xe9, + 0x5b, 0x02, 0x9b, 0x5c, 0x94, 0x51, 0x13, 0xe8, 0xa0, 0x19, 0xce, 0xde, + 0x07, 0x1b, 0xda, 0x39, 0x14, 0xb5, 0x8b, 0xcf, 0x79, 0x3e, 0x2b, 0xb8, + 0x75, 0xab, 0x81, 0xee, 0x5e, 0x08, 0x33, 0xc3, 0x49, 0x5b, 0x4a, 0x9c, + 0x74, 0x34, 0xde, 0x08, 0x61, 0x03, 0x38, 0xe3, 0xd8, 0xff, 0xc5, 0xc0, + 0xb5, 0x40, 0xd5, 0x26, 0x57, 0x85, 0xf1, 0xb7, 0x77, 0xb6, 0x36, 0xe0, + 0x8d, 0x43, 0x3a, 0xef, 0xfe, 0x0f, 0xf7, 0xee, 0x67, 0x6c, 0x7b, 0xd1, + 0x83, 0xf6, 0x10, 0xda, 0x67, 0x04, 0x3a, 0x27, 0xd8, 0x3a, 0xcb, 0x9d, + 0x4c, 0xa6, 0x9a, 0xc7, 0xea, 0x07, 0xc6, 0x76, 0x79, 0x1b, 0x23, 0x4a, + 0x68, 0x2f, 0x14, 0x84, 0x42, 0x79, 0xe8, 0x1f, 0xf2, 0xe6, 0xac, 0x72, + 0xb0, 0xb0, 0xb6, 0x39, 0x95, 0x40, 0xa4, 0x6e, 0x54, 0x2e, 0xb7, 0xb5, + 0x13, 0x70, 0x48, 0x0d, 0x27, 0xed, 0x2c, 0xa2, 0x64, 0x53, 0xb4, 0x04, + 0x84, 0xab, 0xd8, 0xea, 0x2a, 0x8c, 0xac, 0x5b, 0x1d, 0xb8, 0xb2, 0xbe, + 0x55, 0x2b, 0x4a, 0x47, 0xfc, 0xe0, 0x15, 0x78, 0xb6, 0xd6, 0xff, 0x20, + 0xa8, 0x8a, 0xec, 0x8b, 0x30, 0xef, 0xc5, 0xc6, 0xec, 0xa0, 0xdf, 0xd3, + 0xc4, 0x2b, 0x4a, 0xdf, 0xef, 0x5c, 0x46, 0xb3, 0x31, 0xc7, 0x5f, 0x8f, + 0x1e, 0x99, 0x76, 0x81, 0x71, 0x61, 0xdb, 0xc3, 0xc4, 0x0f, 0x66, 0x7b, + 0xd7, 0x44, 0xc7, 0x8d, 0x12, 0x38, 0x71, 0x7c, 0xd8, 0x41, 0xf6, 0x8a, + 0xb9, 0xba, 0xd2, 0x1f, 0xa1, 0x27, 0x64, 0x67, 0x51, 0xb2, 0xaf, 0xea, + 0x02, 0x95, 0x79, 0x20, 0x0a, 0xc8, 0xaa, 0x03, 0x11, 0xb6, 0x8b, 0x7d, + 0x86, 0xb7, 0xef, 0x5e, 0x3f, 0x0b, 0x91, 0x47, 0xf0, 0x43, 0xb4, 0x54, + 0x1d, 0x16, 0x66, 0xe9, 0x63, 0x1a, 0x55, 0xaf, 0x34, 0xad, 0x11, 0x68, + 0x4d, 0x36, 0xb7, 0x0c, 0x6d, 0x4d, 0xed, 0xba, 0x14, 0xe8, 0xf6, 0xe2, + 0x15, 0x64, 0xb6, 0x15, 0x28, 0xbf, 0xd2, 0x4d, 0xb6, 0x6f, 0xca, 0x5f, + 0x81, 0x1b, 0xf0, 0x31, 0xf5, 0xd3, 0xe0, 0x06, 0xc7, 0xf3, 0x0c, 0x18, + 0x91, 0x45, 0x22, 0xa2, 0x30, 0x48, 0x82, 0xeb, 0x42, 0xfc, 0x8f, 0x2a, + 0xa3, 0x1a, 0x8d, 0x84, 0x28, 0x20, 0x16, 0x95, 0xd9, 0x66, 0x67, 0x2b, + 0xef, 0xc6, 0x6e, 0x56, 0x1c, 0x62, 0x74, 0x16, 0x5c, 0x3e, 0x17, 0xd0, + 0xb7, 0xdd, 0x70, 0xb6, 0x0e, 0x79, 0x46, 0xc5, 0x4e, 0x72, 0x46, 0x69, + 0xf5, 0xa1, 0x1c, 0x7b, 0xd5, 0x67, 0x5c, 0xb3, 0x46, 0x4d, 0x18, 0x31, + 0x47, 0x42, 0x20, 0xe6, 0x12, 0x84, 0x4e, 0x16, 0x0f, 0x4a, 0xd0, 0xc4, + 0x91, 0xa3, 0xbd, 0x91, 0xcd, 0x86, 0x4c, 0xcd, 0x4b, 0x2e, 0x62, 0x84, + 0xea, 0x19, 0x2d, 0x21, 0x1a, 0x64, 0xc4, 0xd2, 0x24, 0x92, 0x96, 0x04, + 0x66, 0xb5, 0x4a, 0xe4, 0xa9, 0xd6, 0xaf, 0x12, 0x9b, 0xb5, 0x59, 0xe0, + 0x5c, 0x84, 0x84, 0x7c, 0x68, 0x99, 0xd8, 0x23, 0xa2, 0x15, 0xa7, 0x82, + 0xa5, 0x66, 0x95, 0x8f, 0xfe, 0x57, 0xc1, 0x12, 0x6c, 0x89, 0xe5, 0x5b, + 0x5d, 0x64, 0xdb, 0x81, 0x4f, 0x77, 0x3c, 0xc8, 0x52, 0x4e, 0x2a, 0xd6, + 0x74, 0x3c, 0x4b, 0x11, 0xfc, 0xc1, 0x7c, 0x01, 0xba, 0x0f, 0x0f, 0x57, + 0x8a, 0xbe, 0x5b, 0x16, 0x88, 0x96, 0xe6, 0xe9, 0x60, 0xcf, 0x66, 0xe9, + 0xe6, 0x07, 0xb0, 0x0b, 0xa3, 0xa0, 0xad, 0xdf, 0x70, 0xd4, 0xcb, 0x2e, + 0x33, 0x2f, 0xe5, 0xf2, 0x1e, 0x0d, 0x74, 0x7a, 0xf9, 0x4a, 0x0f, 0x32, + 0xb4, 0xa1, 0xc9, 0xf5, 0x3f, 0x0a, 0x06, 0xf9, 0x67, 0x45, 0x9c, 0xd9, + 0x58, 0xd4, 0x0e, 0x72, 0x55, 0x47, 0x49, 0x9b, 0xab, 0x9c, 0x66, 0xe7, + 0x4d, 0x9a, 0x02, 0x1b, 0x41, 0xad, 0xe5, 0x8c, 0x7f, 0xa1, 0xdc, 0xad, + 0xcd, 0x74, 0xda, 0x9f, 0xfa, 0x87, 0x32, 0xc1, 0x07, 0x8e, 0x9b, 0xef, + 0x28, 0x2f, 0x17, 0x6d, 0xdb, 0x84, 0x4b, 0xa8, 0x7d, 0x31, 0xa8, 0x32, + 0xe4, 0x9a, 0x1e, 0x0e, 0xef, 0x68, 0xf4, 0xac, 0x03, 0x6c, 0x68, 0xcc, + 0x28, 0xbb, 0xfb, 0x21, 0xb8, 0x11, 0xd7, 0xf9, 0xe8, 0x24, 0x37, 0xdf, + 0xe0, 0xb2, 0xef, 0xd6, 0xec, 0xdf, 0xcf, 0xf5, 0x50, 0x19, 0xa3, 0xa9, + 0x1b, 0x01, 0x2e, 0x94, 0x42, 0xb0, 0x14, 0x5d, 0x0e, 0x37, 0x46, 0x4a, + 0x52, 0x53, 0x60, 0x6b, 0x89, 0xc9, 0xca, 0xed, 0x0a, 0x0c, 0x18, 0x33, + 0x3c, 0x40, 0x42, 0x76, 0x7a, 0x7d, 0xb6, 0x10, 0x29, 0x3e, 0x42, 0x75, + 0xa6, 0xbf, 0xcb, 0xd3, 0xdc, 0xe1, 0x00, 0x05, 0x08, 0x25, 0x67, 0x6c, + 0x72, 0xde, 0x26, 0x72, 0x88, 0xbe, 0xfa, 0x05, 0x57, 0x77, 0x78, 0x83, + 0xce, 0xd5, 0x44, 0x49, 0x8b, 0xab, 0xbc, 0xca, 0xd3, 0x1c, 0x34, 0x4a, + 0xaa, 0xc7, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x17, 0x22, 0x2a, 0x2f, 0x36, 0x3d, 0x43}; +#endif /* !MLD_CONFIG_KEYGEN_PCT */ +#endif /* EXPECTED_SIGNATURES_H */ diff --git a/examples/monolithic_build_multilevel/main.c b/examples/monolithic_build_multilevel/main.c new file mode 100644 index 000000000..c1712009a --- /dev/null +++ b/examples/monolithic_build_multilevel/main.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) The mlkem-native project authors + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#include +#include +#include + +#include "expected_signatures.h" +#include "mldsa_native_all.h" +#include "test_only_rng/notrandombytes.h" + +#define CHECK(x) \ + do \ + { \ + int rc; \ + rc = (x); \ + if (!rc) \ + { \ + fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \ + return 1; \ + } \ + } while (0) + +static int test_mldsa44(void) +{ + const char *test_msg = + "This is a test message for ML-DSA digital signature algorithm!"; + const char *test_ctx = "test_context_123"; + size_t msglen = strlen(test_msg); + size_t ctxlen = strlen(test_ctx); + + uint8_t pk[MLDSA44_PUBLICKEYBYTES]; + uint8_t sk[MLDSA44_SECRETKEYBYTES]; + uint8_t sig[MLDSA44_BYTES]; + uint8_t sm[msglen + MLDSA44_BYTES]; /* signed message buffer */ + uint8_t m2[msglen]; /* recovered message buffer */ + size_t siglen; + size_t smlen; + size_t mlen; + + /* WARNING: Test-only + * Normally, you would want to seed a PRNG with trustworthy entropy here. */ + randombytes_reset(); + + printf("ML-DSA-44\n"); + printf("======================\n\n"); + + printf("Message: %s\n", test_msg); + printf("Context: %s\n\n", test_ctx); + + printf("Generating keypair ... "); + + /* Alice generates a public/private key pair */ + CHECK(mldsa44_keypair(pk, sk) == 0); + + printf("DONE\n"); + printf("Signing message... "); + + /* Alice signs the message */ + CHECK(mldsa44_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Verifying signature... "); + + /* Bob verifies Alice's signature */ + CHECK(mldsa44_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, pk) == 0); + + printf("DONE\n"); + printf("Creating signed message... "); + + /* Alternative API: Create a signed message (signature + message combined) */ + CHECK(mldsa44_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Opening signed message... "); + + /* Bob opens the signed message to recover the original message */ + CHECK(mldsa44_open(m2, &mlen, sm, smlen, (const uint8_t *)test_ctx, ctxlen, + pk) == 0); + + printf("DONE\n"); + printf("Compare messages... "); + + /* Verify the recovered message matches the original */ + CHECK(mlen == msglen); + CHECK(memcmp(test_msg, m2, msglen) == 0); + + printf("DONE\n\n"); + + printf("Results:\n"); + printf("--------\n"); + printf("Public key size: %d bytes\n", MLDSA44_PUBLICKEYBYTES); + printf("Secret key size: %d bytes\n", MLDSA44_SECRETKEYBYTES); + printf("Signature size: %d bytes\n", MLDSA44_BYTES); + printf("Message length: %zu bytes\n", msglen); + printf("Signature length: %zu bytes\n", siglen); + printf("Signed msg length: %zu bytes\n", smlen); + +#if !defined(MLD_CONFIG_KEYGEN_PCT) + /* Check against expected signature to make sure that + * we integrated the library correctly */ + printf("Checking deterministic signature... "); + { + /* Compare the generated signature directly against the expected signature + */ + CHECK(siglen == sizeof(expected_signature_44)); + CHECK(memcmp(sig, expected_signature_44, siglen) == 0); + } + printf("DONE\n"); +#else + printf( + "[WARNING] Skipping KAT test since PCT is enabled and modifies PRNG\n"); +#endif + + printf("Signature verification completed successfully!\n"); + + printf("\nAll tests passed! ML-DSA signature verification successful.\n"); + return 0; +} + +static int test_mldsa65(void) +{ + const char *test_msg = + "This is a test message for ML-DSA digital signature algorithm!"; + const char *test_ctx = "test_context_123"; + size_t msglen = strlen(test_msg); + size_t ctxlen = strlen(test_ctx); + + uint8_t pk[MLDSA65_PUBLICKEYBYTES]; + uint8_t sk[MLDSA65_SECRETKEYBYTES]; + uint8_t sig[MLDSA65_BYTES]; + uint8_t sm[msglen + MLDSA65_BYTES]; /* signed message buffer */ + uint8_t m2[msglen]; /* recovered message buffer */ + size_t siglen; + size_t smlen; + size_t mlen; + + /* WARNING: Test-only + * Normally, you would want to seed a PRNG with trustworthy entropy here. */ + randombytes_reset(); + + printf("ML-DSA-65\n"); + printf("======================\n\n"); + + printf("Message: %s\n", test_msg); + printf("Context: %s\n\n", test_ctx); + + printf("Generating keypair ... "); + + /* Alice generates a public/private key pair */ + CHECK(mldsa65_keypair(pk, sk) == 0); + + printf("DONE\n"); + printf("Signing message... "); + + /* Alice signs the message */ + CHECK(mldsa65_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Verifying signature... "); + + /* Bob verifies Alice's signature */ + CHECK(mldsa65_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, pk) == 0); + + printf("DONE\n"); + printf("Creating signed message... "); + + /* Alternative API: Create a signed message (signature + message combined) */ + CHECK(mldsa65_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Opening signed message... "); + + /* Bob opens the signed message to recover the original message */ + CHECK(mldsa65_open(m2, &mlen, sm, smlen, (const uint8_t *)test_ctx, ctxlen, + pk) == 0); + + printf("DONE\n"); + printf("Compare messages... "); + + /* Verify the recovered message matches the original */ + CHECK(mlen == msglen); + CHECK(memcmp(test_msg, m2, msglen) == 0); + + printf("DONE\n\n"); + + printf("Results:\n"); + printf("--------\n"); + printf("Public key size: %d bytes\n", MLDSA65_PUBLICKEYBYTES); + printf("Secret key size: %d bytes\n", MLDSA65_SECRETKEYBYTES); + printf("Signature size: %d bytes\n", MLDSA65_BYTES); + printf("Message length: %zu bytes\n", msglen); + printf("Signature length: %zu bytes\n", siglen); + printf("Signed msg length: %zu bytes\n", smlen); + +#if !defined(MLD_CONFIG_KEYGEN_PCT) + /* Check against expected signature to make sure that + * we integrated the library correctly */ + printf("Checking deterministic signature... "); + { + /* Compare the generated signature directly against the expected signature + */ + CHECK(siglen == sizeof(expected_signature_65)); + CHECK(memcmp(sig, expected_signature_65, siglen) == 0); + } + printf("DONE\n"); +#else + printf( + "[WARNING] Skipping KAT test since PCT is enabled and modifies PRNG\n"); +#endif + + printf("Signature verification completed successfully!\n"); + + printf("\nAll tests passed! ML-DSA signature verification successful.\n"); + return 0; +} + + +static int test_mldsa87(void) +{ + const char *test_msg = + "This is a test message for ML-DSA digital signature algorithm!"; + const char *test_ctx = "test_context_123"; + size_t msglen = strlen(test_msg); + size_t ctxlen = strlen(test_ctx); + + uint8_t pk[MLDSA87_PUBLICKEYBYTES]; + uint8_t sk[MLDSA87_SECRETKEYBYTES]; + uint8_t sig[MLDSA87_BYTES]; + uint8_t sm[msglen + MLDSA87_BYTES]; /* signed message buffer */ + uint8_t m2[msglen]; /* recovered message buffer */ + size_t siglen; + size_t smlen; + size_t mlen; + + /* WARNING: Test-only + * Normally, you would want to seed a PRNG with trustworthy entropy here. */ + randombytes_reset(); + + printf("ML-DSA-87\n"); + printf("======================\n\n"); + + printf("Message: %s\n", test_msg); + printf("Context: %s\n\n", test_ctx); + + printf("Generating keypair ... "); + + /* Alice generates a public/private key pair */ + CHECK(mldsa87_keypair(pk, sk) == 0); + + printf("DONE\n"); + printf("Signing message... "); + + /* Alice signs the message */ + CHECK(mldsa87_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Verifying signature... "); + + /* Bob verifies Alice's signature */ + CHECK(mldsa87_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, pk) == 0); + + printf("DONE\n"); + printf("Creating signed message... "); + + /* Alternative API: Create a signed message (signature + message combined) */ + CHECK(mldsa87_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + (const uint8_t *)test_ctx, ctxlen, sk) == 0); + + printf("DONE\n"); + printf("Opening signed message... "); + + /* Bob opens the signed message to recover the original message */ + CHECK(mldsa87_open(m2, &mlen, sm, smlen, (const uint8_t *)test_ctx, ctxlen, + pk) == 0); + + printf("DONE\n"); + printf("Compare messages... "); + + /* Verify the recovered message matches the original */ + CHECK(mlen == msglen); + CHECK(memcmp(test_msg, m2, msglen) == 0); + + printf("DONE\n\n"); + + printf("Results:\n"); + printf("--------\n"); + printf("Public key size: %d bytes\n", MLDSA87_PUBLICKEYBYTES); + printf("Secret key size: %d bytes\n", MLDSA87_SECRETKEYBYTES); + printf("Signature size: %d bytes\n", MLDSA87_BYTES); + printf("Message length: %zu bytes\n", msglen); + printf("Signature length: %zu bytes\n", siglen); + printf("Signed msg length: %zu bytes\n", smlen); + +#if !defined(MLD_CONFIG_KEYGEN_PCT) + /* Check against expected signature to make sure that + * we integrated the library correctly */ + printf("Checking deterministic signature... "); + { + /* Compare the generated signature directly against the expected signature + */ + CHECK(siglen == sizeof(expected_signature_87)); + CHECK(memcmp(sig, expected_signature_87, siglen) == 0); + } + printf("DONE\n"); +#else + printf( + "[WARNING] Skipping KAT test since PCT is enabled and modifies PRNG\n"); +#endif + + printf("Signature verification completed successfully!\n"); + + printf("\nAll tests passed! ML-DSA signature verification successful.\n"); + return 0; +} + +int main(void) +{ + printf("ML-DSA monolithic_build_multilevel Example\n"); + + if (test_mldsa44() != 0) + { + return 1; + } + + if (test_mldsa65() != 0) + { + return 1; + } + + if (test_mldsa87() != 0) + { + return 1; + } + + return 0; +} diff --git a/examples/monolithic_build_multilevel/mldsa/mldsa_native.c b/examples/monolithic_build_multilevel/mldsa/mldsa_native.c new file mode 120000 index 000000000..107fe39e1 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/mldsa_native.c @@ -0,0 +1 @@ +../../../mldsa/mldsa_native.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/mldsa_native.h b/examples/monolithic_build_multilevel/mldsa/mldsa_native.h new file mode 120000 index 000000000..f25191336 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/mldsa_native.h @@ -0,0 +1 @@ +../../../mldsa/mldsa_native.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/cbmc.h b/examples/monolithic_build_multilevel/mldsa/src/cbmc.h new file mode 120000 index 000000000..9fd253c4c --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/cbmc.h @@ -0,0 +1 @@ +../../../../mldsa/src/cbmc.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/common.h b/examples/monolithic_build_multilevel/mldsa/src/common.h new file mode 120000 index 000000000..7baea8129 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/common.h @@ -0,0 +1 @@ +../../../../mldsa/src/common.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/config.h b/examples/monolithic_build_multilevel/mldsa/src/config.h new file mode 120000 index 000000000..e8185dc91 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/config.h @@ -0,0 +1 @@ +../../../../mldsa/src/config.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/ct.c b/examples/monolithic_build_multilevel/mldsa/src/ct.c new file mode 120000 index 000000000..3f32692cc --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/ct.c @@ -0,0 +1 @@ +../../../../mldsa/src/ct.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/ct.h b/examples/monolithic_build_multilevel/mldsa/src/ct.h new file mode 120000 index 000000000..d46bb57d3 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/ct.h @@ -0,0 +1 @@ +../../../../mldsa/src/ct.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/debug.c b/examples/monolithic_build_multilevel/mldsa/src/debug.c new file mode 120000 index 000000000..e4b0d5d00 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/debug.c @@ -0,0 +1 @@ +../../../../mldsa/src/debug.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/debug.h b/examples/monolithic_build_multilevel/mldsa/src/debug.h new file mode 120000 index 000000000..92949bb27 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/debug.h @@ -0,0 +1 @@ +../../../../mldsa/src/debug.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/fips202 b/examples/monolithic_build_multilevel/mldsa/src/fips202 new file mode 120000 index 000000000..829380ed0 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/fips202 @@ -0,0 +1 @@ +../../../../mldsa/src/fips202 \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/ntt.c b/examples/monolithic_build_multilevel/mldsa/src/ntt.c new file mode 120000 index 000000000..a8ab8e18c --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/ntt.c @@ -0,0 +1 @@ +../../../../mldsa/src/ntt.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/ntt.h b/examples/monolithic_build_multilevel/mldsa/src/ntt.h new file mode 120000 index 000000000..6cf19a6b3 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/ntt.h @@ -0,0 +1 @@ +../../../../mldsa/src/ntt.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/packing.c b/examples/monolithic_build_multilevel/mldsa/src/packing.c new file mode 120000 index 000000000..0da6e8062 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/packing.c @@ -0,0 +1 @@ +../../../../mldsa/src/packing.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/packing.h b/examples/monolithic_build_multilevel/mldsa/src/packing.h new file mode 120000 index 000000000..3dc7c9dae --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/packing.h @@ -0,0 +1 @@ +../../../../mldsa/src/packing.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/params.h b/examples/monolithic_build_multilevel/mldsa/src/params.h new file mode 120000 index 000000000..0a530a256 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/params.h @@ -0,0 +1 @@ +../../../../mldsa/src/params.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/poly.c b/examples/monolithic_build_multilevel/mldsa/src/poly.c new file mode 120000 index 000000000..2a793df40 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/poly.c @@ -0,0 +1 @@ +../../../../mldsa/src/poly.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/poly.h b/examples/monolithic_build_multilevel/mldsa/src/poly.h new file mode 120000 index 000000000..0cdab9983 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/poly.h @@ -0,0 +1 @@ +../../../../mldsa/src/poly.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/poly_kl.c b/examples/monolithic_build_multilevel/mldsa/src/poly_kl.c new file mode 120000 index 000000000..8a27154af --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/poly_kl.c @@ -0,0 +1 @@ +../../../../mldsa/src/poly_kl.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/poly_kl.h b/examples/monolithic_build_multilevel/mldsa/src/poly_kl.h new file mode 120000 index 000000000..f981ad481 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/poly_kl.h @@ -0,0 +1 @@ +../../../../mldsa/src/poly_kl.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/polyvec.c b/examples/monolithic_build_multilevel/mldsa/src/polyvec.c new file mode 120000 index 000000000..33e86a831 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/polyvec.c @@ -0,0 +1 @@ +../../../../mldsa/src/polyvec.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/polyvec.h b/examples/monolithic_build_multilevel/mldsa/src/polyvec.h new file mode 120000 index 000000000..417aa2e0c --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/polyvec.h @@ -0,0 +1 @@ +../../../../mldsa/src/polyvec.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/prehash.c b/examples/monolithic_build_multilevel/mldsa/src/prehash.c new file mode 120000 index 000000000..b47ab34db --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/prehash.c @@ -0,0 +1 @@ +../../../../mldsa/src/prehash.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/prehash.h b/examples/monolithic_build_multilevel/mldsa/src/prehash.h new file mode 120000 index 000000000..c7dec4db1 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/prehash.h @@ -0,0 +1 @@ +../../../../mldsa/src/prehash.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/randombytes.h b/examples/monolithic_build_multilevel/mldsa/src/randombytes.h new file mode 120000 index 000000000..d372260e5 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/randombytes.h @@ -0,0 +1 @@ +../../../../mldsa/src/randombytes.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/reduce.h b/examples/monolithic_build_multilevel/mldsa/src/reduce.h new file mode 120000 index 000000000..e1405ac0a --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/reduce.h @@ -0,0 +1 @@ +../../../../mldsa/src/reduce.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/rounding.h b/examples/monolithic_build_multilevel/mldsa/src/rounding.h new file mode 120000 index 000000000..c58bd9fae --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/rounding.h @@ -0,0 +1 @@ +../../../../mldsa/src/rounding.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/sign.c b/examples/monolithic_build_multilevel/mldsa/src/sign.c new file mode 120000 index 000000000..fad774fba --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/sign.c @@ -0,0 +1 @@ +../../../../mldsa/src/sign.c \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/sign.h b/examples/monolithic_build_multilevel/mldsa/src/sign.h new file mode 120000 index 000000000..2ba1e2a0e --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/sign.h @@ -0,0 +1 @@ +../../../../mldsa/src/sign.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/symmetric.h b/examples/monolithic_build_multilevel/mldsa/src/symmetric.h new file mode 120000 index 000000000..eb4af39ca --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/symmetric.h @@ -0,0 +1 @@ +../../../../mldsa/src/symmetric.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/sys.h b/examples/monolithic_build_multilevel/mldsa/src/sys.h new file mode 120000 index 000000000..7322c1c94 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/sys.h @@ -0,0 +1 @@ +../../../../mldsa/src/sys.h \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa/src/zetas.inc b/examples/monolithic_build_multilevel/mldsa/src/zetas.inc new file mode 120000 index 000000000..b9361143a --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa/src/zetas.inc @@ -0,0 +1 @@ +../../../../mldsa/src/zetas.inc \ No newline at end of file diff --git a/examples/monolithic_build_multilevel/mldsa_native_all.c b/examples/monolithic_build_multilevel/mldsa_native_all.c new file mode 100644 index 000000000..7ce972ba3 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa_native_all.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) The mlkem-native project authors + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#define MLD_CONFIG_FILE "multilevel_config.h" + +/* Three instances of mldsa-native for all security levels */ + +/* Include level-independent code */ +#define MLD_CONFIG_MULTILEVEL_WITH_SHARED +/* Keep level-independent headers at the end of monobuild file */ +#define MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS +#define MLD_CONFIG_PARAMETER_SET 44 +#include "mldsa_native.c" +#undef MLD_CONFIG_PARAMETER_SET +#undef MLD_CONFIG_MULTILEVEL_WITH_SHARED + +/* Exclude level-independent code */ +#define MLD_CONFIG_MULTILEVEL_NO_SHARED +#define MLD_CONFIG_PARAMETER_SET 65 +#include "mldsa_native.c" +#undef MLD_CONFIG_PARAMETER_SET +/* `#undef` all headers at the and of the monobuild file */ +#undef MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS + +#define MLD_CONFIG_PARAMETER_SET 87 +#include "mldsa_native.c" +#undef MLD_CONFIG_PARAMETER_SET diff --git a/examples/monolithic_build_multilevel/mldsa_native_all.h b/examples/monolithic_build_multilevel/mldsa_native_all.h new file mode 100644 index 000000000..005d49a70 --- /dev/null +++ b/examples/monolithic_build_multilevel/mldsa_native_all.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) The mlkem-native project authors + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#ifndef MLD_ALL_H +#define MLD_ALL_H + +#define MLD_CONFIG_API_NO_SUPERCOP + +/* API for MLDSA-44 */ +#define MLD_CONFIG_API_PARAMETER_SET 44 +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa44 +#include +#undef MLD_CONFIG_API_PARAMETER_SET +#undef MLD_CONFIG_API_NAMESPACE_PREFIX +#undef MLD_H + +/* API for MLDSA-65 */ +#define MLD_CONFIG_API_PARAMETER_SET 65 +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa65 +#include +#undef MLD_CONFIG_API_PARAMETER_SET +#undef MLD_CONFIG_API_NAMESPACE_PREFIX +#undef MLD_H + +/* API for MLDSA-87 */ +#define MLD_CONFIG_API_PARAMETER_SET 87 +#define MLD_CONFIG_API_NAMESPACE_PREFIX mldsa87 +#include +#undef MLD_CONFIG_API_PARAMETER_SET +#undef MLD_CONFIG_API_NAMESPACE_PREFIX +#undef MLD_CONFIG_API_NO_SUPERCOP +#undef MLD_H + +#endif /* !MLD_ALL_H */ diff --git a/examples/monolithic_build_multilevel/multilevel_config.h b/examples/monolithic_build_multilevel/multilevel_config.h new file mode 100644 index 000000000..87ce41b46 --- /dev/null +++ b/examples/monolithic_build_multilevel/multilevel_config.h @@ -0,0 +1,437 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +/* References + * ========== + * + * - [FIPS140_3_IG] + * Implementation Guidance for FIPS 140-3 and the Cryptographic Module + * Validation Program National Institute of Standards and Technology + * https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements + * + * - [FIPS204] + * FIPS 204 Module-Lattice-Based Digital Signature Standard + * National Institute of Standards and Technology + * https://csrc.nist.gov/pubs/fips/204/final + */ + +#ifndef MLD_CONFIG_H +#define MLD_CONFIG_H + +/****************************************************************************** + * Name: MLD_CONFIG_PARAMETER_SET + * + * Description: Specifies the parameter set for ML-DSA + * - MLD_CONFIG_PARAMETER_SET=44 corresponds to ML-DSA-44 + * - MLD_CONFIG_PARAMETER_SET=65 corresponds to ML-DSA-65 + * - MLD_CONFIG_PARAMETER_SET=87 corresponds to ML-DSA-87 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#ifndef MLD_CONFIG_PARAMETER_SET +#define MLD_CONFIG_PARAMETER_SET \ + 44 /* Change this for different security strengths */ +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_NAMESPACE_PREFIX + * + * Description: The prefix to use to namespace global symbols from mldsa/. + * + * In a multi-level build (that is, if either + * - MLD_CONFIG_MULTILEVEL_WITH_SHARED, or + * - MLD_CONFIG_MULTILEVEL_NO_SHARED, + * are set, level-dependent symbols will additionally be prefixed + * with the parameter set (44/65/87). + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_NAMESPACE_PREFIX mldsa + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_WITH_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, all MLD_CONFIG_PARAMETER_SET-independent + * code will be included in the build, including code needed only + * for other parameter sets. + * + * Example: TODO: add example + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_WITH_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_NO_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, no MLD_CONFIG_PARAMETER_SET-independent code + * will be included in the build. + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_NO_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of the default configuration file mldsa/config.h. + * + * When you need to build mldsa-native in multiple configurations, + * using varying MLD_CONFIG_FILE can be more convenient + * then configuring everything through CFLAGS. + * + * To use, MLD_CONFIG_FILE _must_ be defined prior + * to the inclusion of any mldsa-native headers. For example, + * it can be set by passing `-DMLD_CONFIG_FILE="..."` + * on the command line. + * + *****************************************************************************/ +/* #define MLD_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_ARITH_BACKEND_FILE + * + * Description: The arithmetic backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is unset, this option + * is ignored. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is set, this option must + * either be undefined or the filename of an arithmetic backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) && \ + !defined(MLD_CONFIG_ARITH_BACKEND_FILE) +#define MLD_CONFIG_ARITH_BACKEND_FILE "native/meta.h" +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_BACKEND_FILE + * + * Description: The FIPS-202 backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 is set, this option + * must either be undefined or the filename of a FIPS202 backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202) && \ + !defined(MLD_CONFIG_FIPS202_BACKEND_FILE) +#define MLD_CONFIG_FIPS202_BACKEND_FILE "fips202/native/auto.h" +#endif +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202X4_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202-X4 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/fips202/fips202x4.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202X4_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_ZEROIZE + * + * Description: In compliance with @[FIPS204, Section 3.6.3], mldsa-native, + * zeroizes intermediate stack buffers before returning from + * function calls. + * + * Set this option and define `mld_zeroize_native` if you want to + * use a custom method to zeroize intermediate stack buffers. + * The default implementation uses SecureZeroMemory on Windows + * and a memset + compiler barrier otherwise. If neither of those + * is available on the target platform, compilation will fail, + * and you will need to use MLD_CONFIG_CUSTOM_ZEROIZE to provide + * a custom implementation of `mld_zeroize_native()`. + * + * WARNING: + * The explicit stack zeroization conducted by mldsa-native + * reduces the likelihood of data leaking on the stack, but + * does not eliminate it! The C standard makes no guarantee about + * where a compiler allocates structures and whether/where it makes + * copies of them. Also, in addition to entire structures, there + * may also be potentially exploitable leakage of individual values + * on the stack. + * + * If you need bullet-proof zeroization of the stack, you need to + * consider additional measures instead of what this feature + * provides. In this case, you can set mld_zeroize_native to a + * no-op. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_ZEROIZE + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_zeroize_native(void *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMCPY + * + * Description: Set this option and define `mld_memcpy` if you want to + * use a custom method to copy memory instead of the standard + * library memcpy function. + * + * The custom implementation must have the same signature and + * behavior as the standard memcpy function: + * void *mld_memcpy(void *dest, const void *src, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMCPY + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memcpy(void *dest, const void *src, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMSET + * + * Description: Set this option and define `mld_memset` if you want to + * use a custom method to set memory instead of the standard + * library memset function. + * + * The custom implementation must have the same signature and + * behavior as the standard memset function: + * void *mld_memset(void *s, int c, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMSET + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memset(void *s, int c, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_RANDOMBYTES + * + * Description: mldsa-native does not provide a secure randombytes + * implementation. Such an implementation has to provided by the + * consumer. + * + * If this option is not set, mldsa-native expects a function + * void randombytes(uint8_t *out, size_t outlen). + * + * Set this option and define `mld_randombytes` if you want to + * use a custom method to sample randombytes with a different name + * or signature. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_RANDOMBYTES + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_randombytes(uint8_t *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT + * + * Description: Compliance with @[FIPS140_3_IG, p.87] requires a + * Pairwise Consistency Test (PCT) to be carried out on a freshly + * generated keypair before it can be exported. + * + * Set this option if such a check should be implemented. + * In this case, crypto_sign_keypair_internal and + * crypto_sign_keypair will return a non-zero error code if the + * PCT failed. + * + * NOTE: This feature will drastically lower the performance of + * key generation. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT */ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + * + * Description: If this option is set, the user must provide a runtime + * function `static inline int mld_break_pct() { ... }` to + * indicate whether the PCT should be made fail. + * + * This option only has an effect if MLD_CONFIG_KEYGEN_PCT is set. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + #if !defined(__ASSEMBLER__) + #include "sys.h" + static MLD_INLINE int mld_break_pct(void) + { + ... return 0/1 depending on whether PCT should be broken ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_INTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of internal API. + * + * The primary use case for this option are single-CU builds, + * in which case this option can be set to `static`. + * + *****************************************************************************/ +#define MLD_CONFIG_INTERNAL_API_QUALIFIER static + +/****************************************************************************** + * Name: MLD_CONFIG_EXTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of mldsa-native's + * public API. + * + * The primary use case for this option are single-CU builds + * where the public API exposed by mldsa-native is wrapped by + * another API in the consuming application. In this case, + * even mldsa-native's public API can be marked `static`. + * + *****************************************************************************/ +/* #define MLD_CONFIG_EXTERNAL_API_QUALIFIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_CT_TESTING_ENABLED + * + * Description: If set, mldsa-native annotates data as secret / public using + * valgrind's annotations VALGRIND_MAKE_MEM_UNDEFINED and + * VALGRIND_MAKE_MEM_DEFINED, enabling various checks for secret- + * dependent control flow of variable time execution (depending + * on the exact version of valgrind installed). + * + *****************************************************************************/ +/* #define MLD_CONFIG_CT_TESTING_ENABLED */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly. + * + * By default, inline assembly is used to implement value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + * Inline assembly is also used to implement a secure zeroization + * function on non-Windows platforms. If this option is set and + * the target platform is not Windows, you MUST set + * MLD_CONFIG_CUSTOM_ZEROIZE and provide a custom zeroization + * function. + * + * If this option is set, MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 and + * and MLD_CONFIG_USE_NATIVE_BACKEND_ARITH will be ignored, and no + * native backends will be used. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM_VALUE_BARRIER + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly for value barriers. + * + * By default, inline assembly (if available) is used to implement + * value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM_VALUE_BARRIER */ + + + +/************************* Config internals ********************************/ + +/* Default namespace + * + * Don't change this. If you need a different namespace, re-define + * MLD_CONFIG_NAMESPACE_PREFIX above instead, and remove the following. + * + * The default MLDSA namespace is + * + * PQCP_MLDSA_NATIVE_MLDSA_ + * + * e.g., PQCP_MLDSA_NATIVE_MLDSA44_ + */ + +#if MLD_CONFIG_PARAMETER_SET == 44 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA44 +#elif MLD_CONFIG_PARAMETER_SET == 65 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA65 +#elif MLD_CONFIG_PARAMETER_SET == 87 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA87 +#endif + +#endif /* !MLD_CONFIG_H */ diff --git a/examples/monolithic_build_multilevel/test_only_rng b/examples/monolithic_build_multilevel/test_only_rng new file mode 120000 index 000000000..b1e04d9b8 --- /dev/null +++ b/examples/monolithic_build_multilevel/test_only_rng @@ -0,0 +1 @@ +../basic/test_only_rng/ \ No newline at end of file From 849d366b54ba28f8d06a92b11b90207d3a75ad58 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Tue, 4 Nov 2025 10:01:26 +0800 Subject: [PATCH 5/7] Clean examples on make clean Signed-off-by: Matthias J. Kannwischer --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 3c6dd1a95..696601437 100644 --- a/Makefile +++ b/Makefile @@ -182,3 +182,7 @@ run_size: \ 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/basic >/dev/null + -make clean -C examples/monolithic_build >/dev/null + -make clean -C examples/monolithic_build_multilevel >/dev/null From 5ebb66ccfd63751fb4cb8f8d8966ba138b1e6a18 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Tue, 4 Nov 2025 10:20:55 +0800 Subject: [PATCH 6/7] Remove stale TODO from bench_mldsa.c Signed-off-by: Matthias J. Kannwischer --- test/bench_mldsa.c | 1 - 1 file changed, 1 deletion(-) diff --git a/test/bench_mldsa.c b/test/bench_mldsa.c index f7d35ba43..e97e343ba 100644 --- a/test/bench_mldsa.c +++ b/test/bench_mldsa.c @@ -114,7 +114,6 @@ static int bench(void) mld_randombytes(ctx, CTXLEN); mld_randombytes(m, MLEN); - /* TODO: shouldn't this be moved to be in the internal function? */ pre[0] = 0; pre[1] = CTXLEN; memcpy(pre + 2, ctx, CTXLEN); From 44ab709106ceb5e3ea8e819f532bde2597c897d3 Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Tue, 4 Nov 2025 11:22:27 +0800 Subject: [PATCH 7/7] Fix C90 issues in example code The C90 tests were not functional before as make clean would not clean the example code. The previous commit fixed that and revealed some C90 issues in the example code. This commit fixes the C90 issues. Signed-off-by: Matthias J. Kannwischer --- examples/basic/main.c | 31 +++++---- examples/bring_your_own_fips202/main.c | 31 +++++---- examples/monolithic_build/main.c | 31 +++++---- examples/monolithic_build_multilevel/main.c | 76 ++++++++++----------- 4 files changed, 88 insertions(+), 81 deletions(-) diff --git a/examples/basic/main.c b/examples/basic/main.c index 5cea9b135..86626de27 100644 --- a/examples/basic/main.c +++ b/examples/basic/main.c @@ -31,19 +31,21 @@ } \ } while (0) +#define TEST_MSG \ + "This is a test message for ML-DSA digital signature algorithm!" +#define TEST_MSG_LEN (sizeof(TEST_MSG) - 1) + int main(void) { - const char *test_msg = - "This is a test message for ML-DSA digital signature algorithm!"; + const char test_msg[] = TEST_MSG; const char *test_ctx = "test_context_123"; - size_t msglen = strlen(test_msg); size_t ctxlen = strlen(test_ctx); uint8_t pk[CRYPTO_PUBLICKEYBYTES]; uint8_t sk[CRYPTO_SECRETKEYBYTES]; uint8_t sig[CRYPTO_BYTES]; - uint8_t sm[msglen + CRYPTO_BYTES]; /* signed message buffer */ - uint8_t m2[msglen]; /* recovered message buffer */ + uint8_t sm[TEST_MSG_LEN + CRYPTO_BYTES]; /* signed message buffer */ + uint8_t m2[TEST_MSG_LEN + CRYPTO_BYTES]; /* recovered message buffer */ size_t siglen; size_t smlen; size_t mlen; @@ -67,21 +69,22 @@ int main(void) printf("Signing message... "); /* Alice signs the message */ - CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, - (const uint8_t *)test_ctx, ctxlen, sk) == 0); + CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, + TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, + sk) == 0); printf("DONE\n"); printf("Verifying signature... "); /* Bob verifies Alice's signature */ - CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, pk) == 0); printf("DONE\n"); printf("Creating signed message... "); /* Alternative API: Create a signed message (signature + message combined) */ - CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); @@ -95,8 +98,8 @@ int main(void) printf("Compare messages... "); /* Verify the recovered message matches the original */ - CHECK(mlen == msglen); - CHECK(memcmp(test_msg, m2, msglen) == 0); + CHECK(mlen == TEST_MSG_LEN); + CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); printf("DONE\n\n"); @@ -105,9 +108,9 @@ int main(void) printf("Public key size: %d bytes\n", CRYPTO_PUBLICKEYBYTES); printf("Secret key size: %d bytes\n", CRYPTO_SECRETKEYBYTES); printf("Signature size: %d bytes\n", CRYPTO_BYTES); - printf("Message length: %zu bytes\n", msglen); - printf("Signature length: %zu bytes\n", siglen); - printf("Signed msg length: %zu bytes\n", smlen); + printf("Message length: %lu bytes\n", TEST_MSG_LEN); + printf("Signature length: %lu bytes\n", (unsigned long)siglen); + printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); #if !defined(MLD_CONFIG_KEYGEN_PCT) /* Check against expected signature to make sure that diff --git a/examples/bring_your_own_fips202/main.c b/examples/bring_your_own_fips202/main.c index 4ca68bf3a..8eecf440e 100644 --- a/examples/bring_your_own_fips202/main.c +++ b/examples/bring_your_own_fips202/main.c @@ -31,19 +31,21 @@ } \ } while (0) +#define TEST_MSG \ + "This is a test message for ML-DSA digital signature algorithm!" +#define TEST_MSG_LEN (sizeof(TEST_MSG) - 1) + int main(void) { - const char *test_msg = - "This is a test message for ML-DSA digital signature algorithm!"; + const char test_msg[] = TEST_MSG; const char *test_ctx = "test_context_123"; - size_t msglen = strlen(test_msg); size_t ctxlen = strlen(test_ctx); uint8_t pk[CRYPTO_PUBLICKEYBYTES]; uint8_t sk[CRYPTO_SECRETKEYBYTES]; uint8_t sig[CRYPTO_BYTES]; - uint8_t sm[msglen + CRYPTO_BYTES]; /* signed message buffer */ - uint8_t m2[msglen]; /* recovered message buffer */ + uint8_t sm[TEST_MSG_LEN + CRYPTO_BYTES]; /* signed message buffer */ + uint8_t m2[TEST_MSG_LEN + CRYPTO_BYTES]; /* recovered message buffer */ size_t siglen; size_t smlen; size_t mlen; @@ -68,21 +70,22 @@ int main(void) printf("Signing message... "); /* Alice signs the message */ - CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, - (const uint8_t *)test_ctx, ctxlen, sk) == 0); + CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, + TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, + sk) == 0); printf("DONE\n"); printf("Verifying signature... "); /* Bob verifies Alice's signature */ - CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, pk) == 0); printf("DONE\n"); printf("Creating signed message... "); /* Alternative API: Create a signed message (signature + message combined) */ - CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); @@ -96,8 +99,8 @@ int main(void) printf("Compare messages... "); /* Verify the recovered message matches the original */ - CHECK(mlen == msglen); - CHECK(memcmp(test_msg, m2, msglen) == 0); + CHECK(mlen == TEST_MSG_LEN); + CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); printf("DONE\n\n"); @@ -106,9 +109,9 @@ int main(void) printf("Public key size: %d bytes\n", CRYPTO_PUBLICKEYBYTES); printf("Secret key size: %d bytes\n", CRYPTO_SECRETKEYBYTES); printf("Signature size: %d bytes\n", CRYPTO_BYTES); - printf("Message length: %zu bytes\n", msglen); - printf("Signature length: %zu bytes\n", siglen); - printf("Signed msg length: %zu bytes\n", smlen); + printf("Message length: %lu bytes\n", TEST_MSG_LEN); + printf("Signature length: %lu bytes\n", (unsigned long)siglen); + printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); #if !defined(MLD_CONFIG_KEYGEN_PCT) /* Check against expected signature to make sure that diff --git a/examples/monolithic_build/main.c b/examples/monolithic_build/main.c index 164526583..97cc3cecd 100644 --- a/examples/monolithic_build/main.c +++ b/examples/monolithic_build/main.c @@ -33,19 +33,21 @@ } \ } while (0) +#define TEST_MSG \ + "This is a test message for ML-DSA digital signature algorithm!" +#define TEST_MSG_LEN (sizeof(TEST_MSG) - 1) + int main(void) { - const char *test_msg = - "This is a test message for ML-DSA digital signature algorithm!"; + const char test_msg[] = TEST_MSG; const char *test_ctx = "test_context_123"; - size_t msglen = strlen(test_msg); size_t ctxlen = strlen(test_ctx); uint8_t pk[CRYPTO_PUBLICKEYBYTES]; uint8_t sk[CRYPTO_SECRETKEYBYTES]; uint8_t sig[CRYPTO_BYTES]; - uint8_t sm[msglen + CRYPTO_BYTES]; /* signed message buffer */ - uint8_t m2[msglen]; /* recovered message buffer */ + uint8_t sm[TEST_MSG_LEN + CRYPTO_BYTES]; /* signed message buffer */ + uint8_t m2[TEST_MSG_LEN + CRYPTO_BYTES]; /* recovered message buffer */ size_t siglen; size_t smlen; size_t mlen; @@ -69,21 +71,22 @@ int main(void) printf("Signing message... "); /* Alice signs the message */ - CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, - (const uint8_t *)test_ctx, ctxlen, sk) == 0); + CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, + TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, + sk) == 0); printf("DONE\n"); printf("Verifying signature... "); /* Bob verifies Alice's signature */ - CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, pk) == 0); printf("DONE\n"); printf("Creating signed message... "); /* Alternative API: Create a signed message (signature + message combined) */ - CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); @@ -97,8 +100,8 @@ int main(void) printf("Compare messages... "); /* Verify the recovered message matches the original */ - CHECK(mlen == msglen); - CHECK(memcmp(test_msg, m2, msglen) == 0); + CHECK(mlen == TEST_MSG_LEN); + CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); printf("DONE\n\n"); @@ -107,9 +110,9 @@ int main(void) printf("Public key size: %d bytes\n", CRYPTO_PUBLICKEYBYTES); printf("Secret key size: %d bytes\n", CRYPTO_SECRETKEYBYTES); printf("Signature size: %d bytes\n", CRYPTO_BYTES); - printf("Message length: %zu bytes\n", msglen); - printf("Signature length: %zu bytes\n", siglen); - printf("Signed msg length: %zu bytes\n", smlen); + printf("Message length: %lu bytes\n", TEST_MSG_LEN); + printf("Signature length: %lu bytes\n", (unsigned long)siglen); + printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); #if !defined(MLD_CONFIG_KEYGEN_PCT) /* Check against expected signature to make sure that diff --git a/examples/monolithic_build_multilevel/main.c b/examples/monolithic_build_multilevel/main.c index c1712009a..e6b9611bd 100644 --- a/examples/monolithic_build_multilevel/main.c +++ b/examples/monolithic_build_multilevel/main.c @@ -24,19 +24,21 @@ } \ } while (0) +#define TEST_MSG \ + "This is a test message for ML-DSA digital signature algorithm!" +#define TEST_MSG_LEN (sizeof(TEST_MSG) - 1) + static int test_mldsa44(void) { - const char *test_msg = - "This is a test message for ML-DSA digital signature algorithm!"; + const char test_msg[] = TEST_MSG; const char *test_ctx = "test_context_123"; - size_t msglen = strlen(test_msg); size_t ctxlen = strlen(test_ctx); uint8_t pk[MLDSA44_PUBLICKEYBYTES]; uint8_t sk[MLDSA44_SECRETKEYBYTES]; uint8_t sig[MLDSA44_BYTES]; - uint8_t sm[msglen + MLDSA44_BYTES]; /* signed message buffer */ - uint8_t m2[msglen]; /* recovered message buffer */ + uint8_t sm[TEST_MSG_LEN + MLDSA44_BYTES]; /* signed message buffer */ + uint8_t m2[TEST_MSG_LEN + MLDSA44_BYTES]; /* recovered message buffer */ size_t siglen; size_t smlen; size_t mlen; @@ -60,21 +62,21 @@ static int test_mldsa44(void) printf("Signing message... "); /* Alice signs the message */ - CHECK(mldsa44_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa44_signature(sig, &siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); printf("Verifying signature... "); /* Bob verifies Alice's signature */ - CHECK(mldsa44_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa44_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, pk) == 0); printf("DONE\n"); printf("Creating signed message... "); /* Alternative API: Create a signed message (signature + message combined) */ - CHECK(mldsa44_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa44_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); @@ -88,8 +90,8 @@ static int test_mldsa44(void) printf("Compare messages... "); /* Verify the recovered message matches the original */ - CHECK(mlen == msglen); - CHECK(memcmp(test_msg, m2, msglen) == 0); + CHECK(mlen == TEST_MSG_LEN); + CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); printf("DONE\n\n"); @@ -98,9 +100,9 @@ static int test_mldsa44(void) printf("Public key size: %d bytes\n", MLDSA44_PUBLICKEYBYTES); printf("Secret key size: %d bytes\n", MLDSA44_SECRETKEYBYTES); printf("Signature size: %d bytes\n", MLDSA44_BYTES); - printf("Message length: %zu bytes\n", msglen); - printf("Signature length: %zu bytes\n", siglen); - printf("Signed msg length: %zu bytes\n", smlen); + printf("Message length: %lu bytes\n", TEST_MSG_LEN); + printf("Signature length: %lu bytes\n", (unsigned long)siglen); + printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); #if !defined(MLD_CONFIG_KEYGEN_PCT) /* Check against expected signature to make sure that @@ -126,17 +128,15 @@ static int test_mldsa44(void) static int test_mldsa65(void) { - const char *test_msg = - "This is a test message for ML-DSA digital signature algorithm!"; + const char test_msg[] = TEST_MSG; const char *test_ctx = "test_context_123"; - size_t msglen = strlen(test_msg); size_t ctxlen = strlen(test_ctx); uint8_t pk[MLDSA65_PUBLICKEYBYTES]; uint8_t sk[MLDSA65_SECRETKEYBYTES]; uint8_t sig[MLDSA65_BYTES]; - uint8_t sm[msglen + MLDSA65_BYTES]; /* signed message buffer */ - uint8_t m2[msglen]; /* recovered message buffer */ + uint8_t sm[TEST_MSG_LEN + MLDSA65_BYTES]; /* signed message buffer */ + uint8_t m2[TEST_MSG_LEN + MLDSA65_BYTES]; /* recovered message buffer */ size_t siglen; size_t smlen; size_t mlen; @@ -160,21 +160,21 @@ static int test_mldsa65(void) printf("Signing message... "); /* Alice signs the message */ - CHECK(mldsa65_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa65_signature(sig, &siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); printf("Verifying signature... "); /* Bob verifies Alice's signature */ - CHECK(mldsa65_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa65_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, pk) == 0); printf("DONE\n"); printf("Creating signed message... "); /* Alternative API: Create a signed message (signature + message combined) */ - CHECK(mldsa65_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa65_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); @@ -188,8 +188,8 @@ static int test_mldsa65(void) printf("Compare messages... "); /* Verify the recovered message matches the original */ - CHECK(mlen == msglen); - CHECK(memcmp(test_msg, m2, msglen) == 0); + CHECK(mlen == TEST_MSG_LEN); + CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); printf("DONE\n\n"); @@ -198,9 +198,9 @@ static int test_mldsa65(void) printf("Public key size: %d bytes\n", MLDSA65_PUBLICKEYBYTES); printf("Secret key size: %d bytes\n", MLDSA65_SECRETKEYBYTES); printf("Signature size: %d bytes\n", MLDSA65_BYTES); - printf("Message length: %zu bytes\n", msglen); - printf("Signature length: %zu bytes\n", siglen); - printf("Signed msg length: %zu bytes\n", smlen); + printf("Message length: %lu bytes\n", TEST_MSG_LEN); + printf("Signature length: %lu bytes\n", (unsigned long)siglen); + printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); #if !defined(MLD_CONFIG_KEYGEN_PCT) /* Check against expected signature to make sure that @@ -227,17 +227,15 @@ static int test_mldsa65(void) static int test_mldsa87(void) { - const char *test_msg = - "This is a test message for ML-DSA digital signature algorithm!"; + const char test_msg[] = TEST_MSG; const char *test_ctx = "test_context_123"; - size_t msglen = strlen(test_msg); size_t ctxlen = strlen(test_ctx); uint8_t pk[MLDSA87_PUBLICKEYBYTES]; uint8_t sk[MLDSA87_SECRETKEYBYTES]; uint8_t sig[MLDSA87_BYTES]; - uint8_t sm[msglen + MLDSA87_BYTES]; /* signed message buffer */ - uint8_t m2[msglen]; /* recovered message buffer */ + uint8_t sm[TEST_MSG_LEN + MLDSA87_BYTES]; /* signed message buffer */ + uint8_t m2[TEST_MSG_LEN + MLDSA87_BYTES]; /* recovered message buffer */ size_t siglen; size_t smlen; size_t mlen; @@ -261,21 +259,21 @@ static int test_mldsa87(void) printf("Signing message... "); /* Alice signs the message */ - CHECK(mldsa87_signature(sig, &siglen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa87_signature(sig, &siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); printf("Verifying signature... "); /* Bob verifies Alice's signature */ - CHECK(mldsa87_verify(sig, siglen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa87_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, pk) == 0); printf("DONE\n"); printf("Creating signed message... "); /* Alternative API: Create a signed message (signature + message combined) */ - CHECK(mldsa87_sign(sm, &smlen, (const uint8_t *)test_msg, msglen, + CHECK(mldsa87_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, (const uint8_t *)test_ctx, ctxlen, sk) == 0); printf("DONE\n"); @@ -289,8 +287,8 @@ static int test_mldsa87(void) printf("Compare messages... "); /* Verify the recovered message matches the original */ - CHECK(mlen == msglen); - CHECK(memcmp(test_msg, m2, msglen) == 0); + CHECK(mlen == TEST_MSG_LEN); + CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); printf("DONE\n\n"); @@ -299,9 +297,9 @@ static int test_mldsa87(void) printf("Public key size: %d bytes\n", MLDSA87_PUBLICKEYBYTES); printf("Secret key size: %d bytes\n", MLDSA87_SECRETKEYBYTES); printf("Signature size: %d bytes\n", MLDSA87_BYTES); - printf("Message length: %zu bytes\n", msglen); - printf("Signature length: %zu bytes\n", siglen); - printf("Signed msg length: %zu bytes\n", smlen); + printf("Message length: %lu bytes\n", TEST_MSG_LEN); + printf("Signature length: %lu bytes\n", (unsigned long)siglen); + printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); #if !defined(MLD_CONFIG_KEYGEN_PCT) /* Check against expected signature to make sure that