Skip to content

Commit 592d20c

Browse files
mkannwischerhanno-becker
authored andcommitted
Examples: Add monolithic_build_multilevel_native
This commit ports the monolithic_build_multilevel_native example from mlkem-native. Resolves #576 Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent fac12db commit 592d20c

File tree

14 files changed

+1163
-1
lines changed

14 files changed

+1163
-1
lines changed

BIBLIOGRAPHY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ source code and documentation.
2828
- [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h)
2929
- [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h)
3030
- [examples/monolithic_build_multilevel/multilevel_config.h](examples/monolithic_build_multilevel/multilevel_config.h)
31+
- [examples/monolithic_build_multilevel_native/multilevel_config.h](examples/monolithic_build_multilevel_native/multilevel_config.h)
3132
- [examples/monolithic_build_native/config_44.h](examples/monolithic_build_native/config_44.h)
3233
- [examples/monolithic_build_native/config_65.h](examples/monolithic_build_native/config_65.h)
3334
- [examples/monolithic_build_native/config_87.h](examples/monolithic_build_native/config_87.h)
@@ -68,6 +69,7 @@ source code and documentation.
6869
- [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h)
6970
- [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h)
7071
- [examples/monolithic_build_multilevel/multilevel_config.h](examples/monolithic_build_multilevel/multilevel_config.h)
72+
- [examples/monolithic_build_multilevel_native/multilevel_config.h](examples/monolithic_build_multilevel_native/multilevel_config.h)
7173
- [examples/monolithic_build_native/config_44.h](examples/monolithic_build_native/config_44.h)
7274
- [examples/monolithic_build_native/config_65.h](examples/monolithic_build_native/config_65.h)
7375
- [examples/monolithic_build_native/config_87.h](examples/monolithic_build_native/config_87.h)

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,4 @@ clean:
222222
-make clean -C examples/monolithic_build >/dev/null
223223
-make clean -C examples/monolithic_build_multilevel >/dev/null
224224
-make clean -C examples/monolithic_build_native >/dev/null
225+
-make clean -C examples/monolithic_build_multilevel_native >/dev/null

auto.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../test/mk/auto.mk
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Copyright (c) The mlkem-native project authors
2+
# Copyright (c) The mldsa-native project authors
3+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4+
5+
.PHONY: build run clean
6+
.DEFAULT_GOAL := all
7+
8+
CC ?= gcc
9+
AR ?= ar
10+
11+
# Adjust CFLAGS if needed
12+
CFLAGS := \
13+
-Wall \
14+
-Wextra \
15+
-Werror=unused-result \
16+
-Wpedantic \
17+
-Werror \
18+
-Wmissing-prototypes \
19+
-Wshadow \
20+
-Wpointer-arith \
21+
-Wredundant-decls \
22+
-Wconversion \
23+
-Wsign-conversion \
24+
-Wno-long-long \
25+
-Wno-unknown-pragmas \
26+
-Wno-unused-command-line-argument \
27+
-Wno-unused-function \
28+
-O3 \
29+
-fomit-frame-pointer \
30+
-std=c99 \
31+
-pedantic \
32+
-MMD \
33+
$(CFLAGS)
34+
35+
# If you want to use the native backends, the compiler needs to know about
36+
# the target architecture. Here, we import the default host detection from
37+
# mldsa-native's tests, but you can write your own or specialize accordingly.
38+
AUTO ?= 1
39+
include auto.mk
40+
41+
# The following only concerns the cross-compilation tests.
42+
# You can likely ignore the following for your application.
43+
#
44+
# Append cross-prefix for cross compilation
45+
# When called from the root Makefile, CROSS_PREFIX has already been added here
46+
ifeq (,$(findstring $(CROSS_PREFIX),$(CC)))
47+
CC := $(CROSS_PREFIX)$(CC)
48+
endif
49+
50+
ifeq (,$(findstring $(CROSS_PREFIX),$(AR)))
51+
AR := $(CROSS_PREFIX)$(AR)
52+
endif
53+
54+
# Part A:
55+
#
56+
# mldsa-native source and header files
57+
#
58+
# Here, the monolithic C file for mldsa-native is directly included in main.c,
59+
# However, we still need to incldue the monolithic assembly file.
60+
MLD_SOURCE_ASM = mldsa/mldsa_native.S
61+
62+
INC=-Imldsa/ -Imldsa/src -I./
63+
64+
# Part B:
65+
#
66+
# Random number generator
67+
#
68+
# !!! WARNING !!!
69+
#
70+
# The randombytes() implementation used here is for TESTING ONLY.
71+
# You MUST NOT use this implementation outside of testing.
72+
#
73+
# !!! WARNING !!!
74+
RNG_SOURCE=$(wildcard test_only_rng/*.c)
75+
76+
# Part C:
77+
#
78+
# Your application source code
79+
APP_SOURCE=$(RNG_SOURCE) main.c
80+
81+
BUILD_DIR=build
82+
BIN=test_binary
83+
84+
#
85+
# Configuration adjustments
86+
#
87+
88+
ASMFLAGS = -DMLD_CONFIG_FILE=\"multilevel_config.h\"
89+
ASMFLAGS += -DMLD_CONFIG_MULTILEVEL_WITH_SHARED
90+
91+
BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN)
92+
93+
MLD_OBJ_C=$(patsubst %,$(BUILD_DIR)/%.o,$(MLD_SOURCE_C))
94+
MLD_OBJ_ASM=$(patsubst %,$(BUILD_DIR)/%.o,$(MLD_SOURCE_ASM))
95+
96+
Q ?= @
97+
98+
$(BUILD_DIR)/%.c.o: %.c
99+
$(Q)echo "CC $^"
100+
$(Q)[ -d $(@D) ] || mkdir -p $(@D)
101+
$(Q)$(CC) -c $(CFLAGS) $(INC) $^ -o $@
102+
103+
$(BUILD_DIR)/%.S.o: %.S
104+
$(Q)echo "AS $^"
105+
$(Q)[ -d $(@D) ] || mkdir -p $(@D)
106+
$(Q)$(CC) -c $(CFLAGS) $(ASMFLAGS) $(INC) $^ -o $@
107+
108+
$(BINARY_NAME_FULL): $(APP_SOURCE) $(MLD_OBJ_ASM)
109+
$(Q)echo "CC $@"
110+
$(Q)[ -d $(@D) ] || mkdir -p $(@D)
111+
$(Q)$(CC) $(CFLAGS) $(INC) $^ -o $@
112+
$(Q)strip -S $@
113+
114+
all: build
115+
116+
build: $(BINARY_NAME_FULL)
117+
118+
run: $(BINARY_NAME_FULL)
119+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL)
120+
121+
clean:
122+
rm -rf $(BUILD_DIR)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
2+
3+
# Multi-level mldsa-native in a single compilation unit, with native code
4+
5+
This directory contains a minimal example for how to build multiple instances of mldsa-native in a single compilation
6+
unit, while additionally linking assembly sources from native code.
7+
8+
The auto-generated source file [mldsa_native.c](mldsa/mldsa_native.c) includes all mldsa-native C source
9+
files. Moreover, it clears all `#define`s clauses set by mldsa-native at the end, and is hence amenable to multiple
10+
inclusion in another compilation unit.
11+
12+
The manually written source file [mldsa_native_all.c](mldsa_native_all.c) includes
13+
[mldsa_native.c](mldsa/mldsa_native.c) three times, each time using the fixed config
14+
[multilevel_config.h](multilevel_config.h), but changing the security level (specified
15+
by `MLD_CONFIG_PARAMETER_SET`) every time. For each inclusion, it sets `MLD_CONFIG_FILE`
16+
appropriately first, and then includes the monobuild:
17+
```C
18+
/* Three instances of mldsa-native for all security levels */
19+
20+
#define MLD_CONFIG_FILE "multilevel_config.h"
21+
22+
/* Include level-independent code */
23+
#define MLD_CONFIG_MULTILEVEL_WITH_SHARED 1
24+
/* Keep level-independent headers at the end of monobuild file */
25+
#define MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS
26+
#define MLD_CONFIG_PARAMETER_SET 44
27+
#include "mldsa_native.c"
28+
#undef MLD_CONFIG_MULTILEVEL_WITH_SHARED
29+
#undef MLD_CONFIG_PARAMETER_SET
30+
31+
/* Exclude level-independent code */
32+
#define MLD_CONFIG_MULTILEVEL_NO_SHARED
33+
#define MLD_CONFIG_PARAMETER_SET 65
34+
#include "mldsa_native.c"
35+
/* `#undef` all headers at the and of the monobuild file */
36+
#undef MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS
37+
#undef MLD_CONFIG_PARAMETER_SET
38+
39+
#define MLD_CONFIG_PARAMETER_SET 87
40+
#include "mldsa_native.c"
41+
#undef MLD_CONFIG_PARAMETER_SET
42+
```
43+
44+
Note the setting `MLD_CONFIG_MULTILEVEL_WITH_SHARED` which forces the inclusion of all level-independent
45+
code in the ML_DSA-44 build, and the setting `MLD_CONFIG_MULTILEVEL_NO_SHARED`, which drops all
46+
level-independent code in the subsequent builds. Finally, `MLD_CONFIG_MONOBUILD_KEEP_SHARED_HEADERS` entails that
47+
[mldsa_native.c](mldsa/mldsa_native.c) does not `#undefine` the `#define` clauses from level-independent files.
48+
49+
Since we embed [mldsa_native_all.c](mldsa_native_all.c) directly into the application source [main.c](main.c), we don't
50+
need a header for function declarations. However, we still import [mldsa_native.h](../../mldsa/mldsa_native.h) once
51+
with `MLD_CONFIG_API_CONSTANTS_ONLY`, for definitions of the sizes of the key material and signatures.
52+
Excerpt from [main.c](main.c):
53+
54+
```c
55+
#include "mldsa_native_all.c"
56+
57+
#define MLD_CONFIG_API_CONSTANTS_ONLY
58+
#include <mldsa_native.h>
59+
```
60+
61+
## Usage
62+
63+
Build this example with `make build`, run with `make run`.
64+
65+
**WARNING:** The `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation
66+
outside of testing.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../test/mk/auto.mk
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../monolithic_build_multilevel/expected_signatures.h

0 commit comments

Comments
 (0)