Skip to content

Commit ebcd246

Browse files
committed
Examples: Add example for restartable signing via signing hooks
Signed-off-by: Hanno Becker <beckphan@amazon.co.uk>
1 parent 7d85139 commit ebcd246

14 files changed

Lines changed: 1311 additions & 2 deletions

File tree

.github/actions/config-variations/action.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ runs:
3636
sign_hook: false # SIGN_HOOK_RESUME is incompatible with KEYGEN_PCT
3737
opt: ${{ inputs.opt }}
3838
examples: true
39-
extra_args: "--exclude-example basic_deterministic"
39+
# basic_deterministic and restartable_sign set MLD_CONFIG_NO_RANDOMIZED_API,
40+
# which is incompatible with MLD_CONFIG_KEYGEN_PCT.
41+
extra_args: "--exclude-example basic_deterministic --exclude-example restartable_sign"
4042
- name: "REDUCE_RAM"
4143
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'reduce-ram') }}
4244
uses: ./.github/actions/multi-functest
@@ -66,7 +68,9 @@ runs:
6668
sign_hook: false # SIGN_HOOK_RESUME is incompatible with KEYGEN_PCT
6769
opt: ${{ inputs.opt }}
6870
examples: true
69-
extra_args: "--exclude-example basic_deterministic"
71+
# basic_deterministic and restartable_sign set MLD_CONFIG_NO_RANDOMIZED_API,
72+
# which is incompatible with MLD_CONFIG_KEYGEN_PCT.
73+
extra_args: "--exclude-example basic_deterministic --exclude-example restartable_sign"
7074
- name: "PCT enabled + broken"
7175
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'pct-enabled-broken') }}
7276
shell: bash

.github/workflows/base.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ jobs:
243243
- name: basic_lowram
244244
run: |
245245
CFLAGS="-O0" make run -C examples/basic_lowram
246+
- name: restartable_sign
247+
run: |
248+
CFLAGS="-O0" make run -C examples/restartable_sign
246249
- name: bring_your_own_fips202
247250
run: |
248251
CFLAGS="-O0" make run -C examples/bring_your_own_fips202

examples/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ See [basic_deterministic](basic_deterministic) for a basic example of how to bui
1616

1717
See [basic_lowram](basic_lowram) for a basic example of how to build a single instance of mldsa-native with reduced RAM usage (`MLD_CONFIG_REDUCE_RAM`). This is useful for embedded systems with tight RAM constraints.
1818

19+
## Restartable signing
20+
21+
See [restartable_sign](restartable_sign) for a minimal example of restartable signing using the signing hooks
22+
(`MLD_CONFIG_SIGN_HOOK_RESUME` / `_ATTEMPT` / `_FINISH`). It pauses the rejection-sampling loop and resumes it on a
23+
later call -- bounding per-call runtime while reproducing the same signature as an uninterrupted run -- keeping the
24+
resume state in a global variable.
25+
1926
## Multi-level build (C only)
2027

2128
See [multilevel_build](multilevel_build) for an example of how to build one instance of mldsa-native per security level,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
2+
3+
build

examples/restartable_sign/Makefile

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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+
10+
# Adjust CFLAGS if needed
11+
CFLAGS := \
12+
-Wall \
13+
-Wextra \
14+
-Werror=unused-result \
15+
-Wpedantic \
16+
-Werror \
17+
-Wmissing-prototypes \
18+
-Wshadow \
19+
-Wpointer-arith \
20+
-Wredundant-decls \
21+
-Wconversion \
22+
-Wsign-conversion \
23+
-Wno-long-long \
24+
-Wno-unknown-pragmas \
25+
-Wno-unused-command-line-argument \
26+
-O3 \
27+
-fomit-frame-pointer \
28+
-std=c99 \
29+
-pedantic \
30+
-MMD \
31+
$(CFLAGS)
32+
33+
# If you want to use the native backends, the compiler needs to know about
34+
# the target architecture. Here, we import the default host detection from
35+
# mldsa-native's tests, but you can write your own or specialize accordingly.
36+
AUTO ?= 1
37+
include auto.mk
38+
39+
# The following only concerns the cross-compilation tests.
40+
# You can likely ignore the following for your application.
41+
#
42+
# Append cross-prefix for cross compilation
43+
# When called from the root Makefile, CROSS_PREFIX has already been added here
44+
ifeq (,$(findstring $(CROSS_PREFIX),$(CC)))
45+
CC := $(CROSS_PREFIX)$(CC)
46+
endif
47+
48+
# Part A:
49+
#
50+
# mldsa-native source and header files
51+
#
52+
# If you are not concerned about minimizing for a specific backend,
53+
# you can just include _all_ source files into your build.
54+
#
55+
# In this example, we compile the individual mldsa-native source files directly.
56+
# Alternatively, you can compile the 'monobuild' source file mldsa_native.c.
57+
# See examples/monolithic_build for that.
58+
MLD_SOURCE=$(wildcard \
59+
mldsa_native/src/*.c \
60+
mldsa_native/src/**/*.c \
61+
mldsa_native/src/**/**/*.c \
62+
mldsa_native/src/**/**/**/*.c)
63+
64+
INC=-Imldsa_native
65+
66+
# Part B:
67+
#
68+
# Your application source code
69+
APP_SOURCE=$(wildcard *.c)
70+
71+
ALL_SOURCE=$(MLD_SOURCE) $(APP_SOURCE)
72+
73+
BUILD_DIR=build
74+
BIN=test_binary
75+
76+
BINARY_NAME_FULL_44=$(BUILD_DIR)/$(BIN)44
77+
BINARY_NAME_FULL_65=$(BUILD_DIR)/$(BIN)65
78+
BINARY_NAME_FULL_87=$(BUILD_DIR)/$(BIN)87
79+
BINARIES_FULL=$(BINARY_NAME_FULL_44) $(BINARY_NAME_FULL_65) $(BINARY_NAME_FULL_87)
80+
81+
$(BINARY_NAME_FULL_44): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=44
82+
$(BINARY_NAME_FULL_65): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=65
83+
$(BINARY_NAME_FULL_87): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=87
84+
85+
$(BINARIES_FULL): $(ALL_SOURCE)
86+
echo "$@"
87+
mkdir -p $(BUILD_DIR)
88+
$(CC) $(CFLAGS) $(INC) $^ -o $@
89+
90+
all: build
91+
92+
build: $(BINARIES_FULL)
93+
94+
run: $(BINARIES_FULL)
95+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_44)
96+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_65)
97+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_87)
98+
99+
clean:
100+
rm -rf $(BUILD_DIR)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
2+
3+
4+
This directory contains a minimal example of *restartable signing*: pausing the
5+
ML-DSA rejection-sampling loop and resuming it later, so that each signing call
6+
has a bounded runtime while the overall result is identical to an uninterrupted
7+
signature.
8+
9+
## Use Case
10+
11+
ML-DSA signing retries until a candidate signature passes rejection sampling,
12+
so a single call has an unbounded runtime. On a system with strict timing
13+
constraints you may want to cap the work done per call and continue later.
14+
The signing hooks let you do that while retaining functional equivalence to
15+
an uninterrupted ML-DSA signature operation.
16+
17+
## Configuration
18+
19+
The configuration file [mldsa_native_config.h](mldsa_native/mldsa_native_config.h) sets:
20+
- `MLD_CONFIG_SIGN_HOOK_RESUME` / `_ATTEMPT` / `_FINISH`: the three hooks around
21+
the rejection-sampling loop. The attempt hook may pause signing (which then
22+
returns `MLD_ERR_SIGNING_PAUSED`); the resume hook continues from the paused
23+
attempt on the next call.
24+
- `MLD_CONFIG_NO_RANDOMIZED_API`: resuming is only sound when the randomness is
25+
fixed across calls, so the caller drives the deterministic internal API.
26+
- `MLD_CONFIG_NAMESPACE_PREFIX`: Symbol prefix (set to `mldsa`)
27+
28+
## Resume state: global vs. context
29+
30+
This example keeps the resume state in a **global variable**, so the hooks take
31+
no arguments beyond the attempt counter. That is the simplest integration and
32+
suits a single-threaded caller signing one message at a time.
33+
34+
For concurrent or interleaved signing, keep the state **per caller** instead:
35+
enable `MLD_CONFIG_CONTEXT_PARAMETER`, give it your state type, and every public
36+
API function gains a trailing context argument that is forwarded to the hooks.
37+
See [test/src/test_sign_hook.c](../../test/src/test_sign_hook.c) for that
38+
variant.
39+
40+
## Notes
41+
42+
- This is incompatible with `MLD_CONFIG_KEYGEN_PCT` (pairwise consistency test):
43+
the PCT runs a single internal signature that cannot be resumed.
44+
45+
## Usage
46+
47+
```bash
48+
make build # Build the example
49+
make run # Run the example
50+
```

examples/restartable_sign/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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../test/test_vectors/expected_test_vectors.h

0 commit comments

Comments
 (0)