Skip to content

Commit e39af6a

Browse files
committed
Add bring_your_own_fips202 example
This adds an example demonstrating how mldsa-native can be used with a custom FIPS202 implementation. We use https://github.com/mjosaarinen/tiny_sha3 for demonstration. The example closely follows https://github.com/pq-code-package/mlkem-native/tree/main/examples/bring_your_own_fips202 Resolves #556 Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent 4bffdec commit e39af6a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1272
-5
lines changed

BIBLIOGRAPHY.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ source code and documentation.
3434
- National Institute of Standards and Technology
3535
* URL: https://csrc.nist.gov/pubs/fips/202/final
3636
* Referenced from:
37+
- [FIPS202.md](FIPS202.md)
3738
- [README.md](README.md)
3839

3940
### `FIPS204`
@@ -243,9 +244,22 @@ source code and documentation.
243244
* Referenced from:
244245
- [examples/basic/test_only_rng/notrandombytes.c](examples/basic/test_only_rng/notrandombytes.c)
245246
- [examples/basic/test_only_rng/notrandombytes.h](examples/basic/test_only_rng/notrandombytes.h)
247+
- [examples/bring_your_own_fips202/test_only_rng/notrandombytes.c](examples/bring_your_own_fips202/test_only_rng/notrandombytes.c)
248+
- [examples/bring_your_own_fips202/test_only_rng/notrandombytes.h](examples/bring_your_own_fips202/test_only_rng/notrandombytes.h)
246249
- [test/notrandombytes/notrandombytes.c](test/notrandombytes/notrandombytes.c)
247250
- [test/notrandombytes/notrandombytes.h](test/notrandombytes/notrandombytes.h)
248251

252+
### `tiny_sha3`
253+
254+
* tiny_sha3
255+
* Author(s):
256+
- Markku-Juhani O. Saarinen
257+
* URL: https://github.com/mjosaarinen/tiny_sha3
258+
* Referenced from:
259+
- [FIPS202.md](FIPS202.md)
260+
- [README.md](README.md)
261+
- [examples/bring_your_own_fips202/README.md](examples/bring_your_own_fips202/README.md)
262+
249263
### `tweetfips`
250264

251265
* 'tweetfips202' FIPS202 implementation

BIBLIOGRAPHY.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@
106106
- Schwabe, Peter
107107
url: https://keccak.team/2015/tweetfips202.html
108108

109+
- id: tiny_sha3
110+
name: tiny_sha3
111+
author: Saarinen, Markku-Juhani O.
112+
url: https://github.com/mjosaarinen/tiny_sha3
113+
109114
- id: libmceliece
110115
name: libmceliece implementation of Classic McEliece
111116
author:

FIPS202.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
2+
3+
# Replacing FIPS-202
4+
5+
If your library has a FIPS-202[^FIPS202] implementation, you can use it instead of the one shipped with mldsa-native.
6+
7+
1. Replace `mldsa/fips202/*` by your own FIPS-202 implementation.
8+
2. Provide replacements for the headers [`mldsa/fips202/fips202.h`](mldsa/fips202/fips202.h) and [`mldsa/fips202/fips202x4.h`](mldsa/fips202/fips202x4.h) and the
9+
functionalities specified therein:
10+
* Structure definitions for `mld_shake128ctx`, `mld_shake256ctx`, `mld_shake128x4ctx`, and `mld_shake256x4ctx`
11+
* `mld_shake128_init()`: Initialize a SHAKE-128 context
12+
* `mld_shake128_absorb()`: Absorb data into a SHAKE-128 context (can be called multiple times)
13+
* `mld_shake128_finalize()`: Finalize the absorb phase of a SHAKE-128 context
14+
* `mld_shake128_squeeze()`: Squeeze data from a SHAKE-128 context (can be called multiple times)
15+
* `mld_shake128_release()`: Release and securely zero a SHAKE-128 context after use
16+
* `mld_shake256_init()`: Initialize a SHAKE-256 context
17+
* `mld_shake256_absorb()`: Absorb data into a SHAKE-256 context (can be called multiple times)
18+
* `mld_shake256_finalize()`: Finalize the absorb phase of a SHAKE-256 context
19+
* `mld_shake256_squeeze()`: Squeeze data from a SHAKE-256 context (can be called multiple times)
20+
* `mld_shake256_release()`: Release and securely zero a SHAKE-256 context after use
21+
* `mld_shake256()`: One-shot SHAKE-256 operation
22+
* `mld_shake128x4_init()`: Initialize a 4x-batched SHAKE-128 context
23+
* `mld_shake128x4_absorb_once()`: Initialize and absorb into a 4x-batched SHAKE-128 context in one step
24+
* `mld_shake128x4_squeezeblocks()`: Squeeze blocks from a 4x-batched SHAKE-128 context
25+
* `mld_shake128x4_release()`: Release a 4x-batched SHAKE-128 context after use
26+
* `mld_shake256x4_init()`: Initialize a 4x-batched SHAKE-256 context
27+
* `mld_shake256x4_absorb_once()`: Initialize and absorb into a 4x-batched SHAKE-256 context in one step
28+
* `mld_shake256x4_squeezeblocks()`: Squeeze blocks from a 4x-batched SHAKE-256 context
29+
* `mld_shake256x4_release()`: Release a 4x-batched SHAKE-256 context after use
30+
31+
See [`mldsa/fips202/fips202.h`](mldsa/fips202/fips202.h) and [`mldsa/fips202/fips202x4.h`](mldsa/fips202/fips202x4.h) for more details. Note that the structure
32+
definitions may differ from those shipped with mldsa-native.
33+
34+
## Example
35+
36+
See [`examples/bring_your_own_fips202/`](examples/bring_your_own_fips202/) for an example how to use a custom FIPS-202
37+
implementation with tiny_sha3[^tiny_sha3].
38+
39+
<!--- bibliography --->
40+
[^FIPS202]: National Institute of Standards and Technology: FIPS202 SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions, [https://csrc.nist.gov/pubs/fips/202/final](https://csrc.nist.gov/pubs/fips/202/final)
41+
[^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3)

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ offers backends for C, AArch64, and x86_64 - if you'd like contribute new backen
6262

6363
Once mldsa-native reaches production readiness, you will be able to import [mldsa](mldsa) into your project's source tree and build using your preferred build system. The build system provided in this repository is for development purposes only.
6464

65-
### Will I be able to bring my own FIPS-202?
65+
### Can I bring my own FIPS-202?
6666

6767
mldsa-native relies on and comes with an implementation of FIPS-202[^FIPS202]. If your library has its own FIPS-202 implementation, you
68-
can use it instead of the one shipped with mldsa-native.
68+
can use it instead of the one shipped with mldsa-native. See [FIPS202.md](FIPS202.md), and [examples/bring_your_own_fips202](examples/bring_your_own_fips202)
69+
for an example using tiny_sha3[^tiny_sha3].
6970

7071
### Will I need to use the assembly backends?
7172

@@ -124,3 +125,4 @@ through the [PQCA Discord](https://discord.com/invite/xyVnwzfg5R).
124125
[^NIST_FAQ]: National Institute of Standards and Technology: Post-Quantum Cryptography FAQs, [https://csrc.nist.gov/Projects/post-quantum-cryptography/faqs#Rdc7](https://csrc.nist.gov/Projects/post-quantum-cryptography/faqs#Rdc7)
125126
[^NIST_FIPS204_SEC6]: National Institute of Standards and Technology: FIPS 204 Section 6 Guidance, [https://csrc.nist.gov/csrc/media/Projects/post-quantum-cryptography/documents/faq/fips204-sec6-03192025.pdf](https://csrc.nist.gov/csrc/media/Projects/post-quantum-cryptography/documents/faq/fips204-sec6-03192025.pdf)
126127
[^REF]: Bai, Ducas, Kiltz, Lepoint, Lyubashevsky, Schwabe, Seiler, Stehlé: CRYSTALS-Dilithium reference implementation, [https://github.com/pq-crystals/dilithium/tree/master/ref](https://github.com/pq-crystals/dilithium/tree/master/ref)
128+
[^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
2+
3+
build/
4+
*.d
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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+
# In this example, we compile the individual mldsa-native source files directly.
53+
# Alternatively, you can compile the 'monobuild' source file mldsa_native.c.
54+
# See examples/monolithic_build for that.
55+
MLD_SOURCE=$(wildcard \
56+
mldsa_native/*.c \
57+
mldsa_native/**/*.c \
58+
mldsa_native/**/**/*.c \
59+
mldsa_native/**/**/**/*.c)
60+
61+
INC=-Imldsa_native/
62+
63+
# Part B:
64+
#
65+
# Custom FIPS-202 implementation
66+
FIPS202_SOURCE=custom_fips202/tiny_sha3/sha3.c
67+
68+
# Part C:
69+
#
70+
# Random number generator
71+
#
72+
# !!! WARNING !!!
73+
#
74+
# The randombytes() implementation used here is for TESTING ONLY.
75+
# You MUST NOT use this implementation outside of testing.
76+
#
77+
# !!! WARNING !!!
78+
RNG_SOURCE=$(wildcard test_only_rng/*.c)
79+
80+
# Part D:
81+
#
82+
# Your application source code
83+
APP_SOURCE=$(wildcard *.c)
84+
85+
ALL_SOURCE=$(MLD_SOURCE) $(FIPS202_SOURCE) $(RNG_SOURCE) $(APP_SOURCE)
86+
87+
#
88+
# Configuration adjustments
89+
#
90+
91+
# Pick prefix
92+
CFLAGS += -DMLD_CONFIG_NAMESPACE_PREFIX=mldsa
93+
# Tell mldsa-native where to find the header for the custom FIPS202
94+
# The structure names and function signatures exposed in those headers must
95+
# match those from the standard FIPS202 implementation. See FIPS202.md.
96+
CFLAGS += -DMLD_CONFIG_FIPS202_CUSTOM_HEADER="\"../custom_fips202/fips202.h\""
97+
CFLAGS += -DMLD_CONFIG_FIPS202X4_CUSTOM_HEADER="\"../custom_fips202/fips202x4.h\""
98+
99+
BUILD_DIR=build
100+
BIN=test_binary
101+
102+
BINARY_NAME_FULL_44=$(BUILD_DIR)/$(BIN)44
103+
BINARY_NAME_FULL_65=$(BUILD_DIR)/$(BIN)65
104+
BINARY_NAME_FULL_87=$(BUILD_DIR)/$(BIN)87
105+
BINARIES_FULL=$(BINARY_NAME_FULL_44) $(BINARY_NAME_FULL_65) $(BINARY_NAME_FULL_87)
106+
107+
$(BINARY_NAME_FULL_44): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=44
108+
$(BINARY_NAME_FULL_65): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=65
109+
$(BINARY_NAME_FULL_87): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=87
110+
111+
$(BINARIES_FULL): $(ALL_SOURCE)
112+
echo "$@"
113+
mkdir -p $(BUILD_DIR)
114+
$(CC) $(CFLAGS) $(INC) $^ -o $@
115+
116+
all: build
117+
118+
build: $(BINARIES_FULL)
119+
120+
run: $(BINARIES_FULL)
121+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_44)
122+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_65)
123+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_87)
124+
125+
clean:
126+
rm -rf $(BUILD_DIR)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
2+
3+
# Bring your own FIPS-202
4+
5+
This directory contains a minimal example for how to use mldsa-native as a code package, with a custom FIPS-202
6+
implementation. We use tiny_sha3[^tiny_sha3] as an example.
7+
8+
## Components
9+
10+
An application using mldsa-native with a custom FIPS-202 implementation needs the following:
11+
12+
1. Arithmetic part of the mldsa-native source tree: [`mldsa/`](../../mldsa)
13+
2. A secure pseudo random number generator, implementing [`randombytes.h`](../../mldsa/randombytes.h).
14+
3. A custom FIPS-202 with `fips202.h` and `fips202x4.h` headers compatible with
15+
[`mldsa/fips202/fips202.h`](../../mldsa/fips202/fips202.h) and [`mldsa/fips202/fips202x4.h`](../../mldsa/fips202/fips202x4.h).
16+
4. The application source code
17+
18+
**WARNING:** The `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation
19+
outside of testing.
20+
21+
## Usage
22+
23+
Build this example with `make build`, run with `make run`.
24+
25+
## Custom FIPS-202 Implementation
26+
27+
This example uses tiny_sha3 as the underlying Keccak/SHA3 implementation. The wrapper headers in `custom_fips202/`
28+
adapt the tiny_sha3 API to match the API expected by mldsa-native.
29+
30+
Note that the `fips202x4.h` implementation provided here is a simple serial implementation that does not provide
31+
any performance benefits from parallelization. For production use, consider using an optimized parallel implementation.
32+
33+
## Verification
34+
35+
This example uses the same test vectors as the basic example (via a symlink to `expected_signatures.h`) and verifies
36+
that the custom FIPS-202 implementation produces identical results to the default implementation. This ensures that
37+
the wrapper is correctly implementing the required API.
38+
39+
<!--- bibliography --->
40+
[^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../test/mk/auto.mk

0 commit comments

Comments
 (0)