# Builds the external post-quantum primitives Circe depends on: # - mlkem-native -> ML-KEM-768 # - mldsa-native -> ML-DSA-44 # # Both are compiled as single-compilation-unit (monolithic) builds: one C unit # plus one assembly unit per library. The parameter set, namespace and native # backend selection live in the config headers under contrib/config/, which are # pulled in via -DML{K,D}_CONFIG_FILE. # # Each consumer of these libraries must still provide a randombytes() # implementation: int randombytes(uint8_t *out, size_t outlen); cc = meson.get_compiler('c') # --------------------------------------------------------------------------- # Native-backend architecture flags # # The config headers enable the native backends whenever the compiler targets # AArch64 or x86-64. Here we hand the compiler the ISA flags those backends # need; on any other architecture we add nothing and the portable C backends # are used instead. # --------------------------------------------------------------------------- native_arch_args = [] cpu = host_machine.cpu_family() if cpu == 'x86_64' # AVX2 arithmetic backend + BMI2 for the Keccak/rejection-sampling paths. foreach arg : ['-mavx2', '-mbmi2'] if cc.has_argument(arg) native_arch_args += arg endif endforeach elif cpu == 'aarch64' # NEON arithmetic backend + the Armv8.4 SHA3 extension for native Keccak. if cc.has_argument('-march=armv8.4-a+sha3') native_arch_args += '-march=armv8.4-a+sha3' endif endif contrib_config_inc = include_directories('config') # Freestanding, matching the rest of Circe: no libc is linked, and the config # headers route the libraries' memcpy/memset/zeroize through common's # circe_memcpy/circe_memset (hence the common_dep below). pqc_c_args = [ '-O3', '-ffreestanding', '-fno-stack-protector', # no libc: don't emit __stack_chk_fail references '-fomit-frame-pointer', ] + native_arch_args # --------------------------------------------------------------------------- # mlkem-native -> ML-KEM-768 # --------------------------------------------------------------------------- mlkem_inc = include_directories('mlkem-native/mlkem') mlkem_config_arg = '-DMLK_CONFIG_FILE="circe_mlkem_config.h"' mlkem_lib = static_library( 'circe-mlkem', [ 'mlkem-native/mlkem/mlkem_native.c', 'mlkem-native/mlkem/mlkem_native_asm.S', ], c_args: pqc_c_args + [mlkem_config_arg], include_directories: [mlkem_inc, contrib_config_inc], dependencies: [common_dep], ) mlkem_dep = declare_dependency( link_with: mlkem_lib, include_directories: [mlkem_inc, contrib_config_inc], compile_args: [mlkem_config_arg], dependencies: [common_dep], ) set_variable(meson.project_name() + '_mlkem_dep', mlkem_dep) # --------------------------------------------------------------------------- # mldsa-native -> ML-DSA-44 # --------------------------------------------------------------------------- mldsa_inc = include_directories('mldsa-native/mldsa') mldsa_config_arg = '-DMLD_CONFIG_FILE="circe_mldsa_config.h"' mldsa_lib = static_library( 'circe-mldsa', [ 'mldsa-native/mldsa/mldsa_native.c', 'mldsa-native/mldsa/mldsa_native_asm.S', ], c_args: pqc_c_args + [mldsa_config_arg], include_directories: [mldsa_inc, contrib_config_inc], dependencies: [common_dep], ) mldsa_dep = declare_dependency( link_with: mldsa_lib, include_directories: [mldsa_inc, contrib_config_inc], compile_args: [mldsa_config_arg], dependencies: [common_dep], ) set_variable(meson.project_name() + '_mldsa_dep', mldsa_dep)