Skip to content

Commit 3d884a2

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 94311a7 commit 3d884a2

File tree

18 files changed

+1236
-6
lines changed

18 files changed

+1236
-6
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)

examples/basic/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# (SPDX-License-Identifier: CC-BY-4.0)
1+
# Copyright (c) The mldsa-native project authors
2+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
23

34
.PHONY: build run clean size
45
.DEFAULT_GOAL := all
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: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Copyright (c) The mldsa-native project authors
2+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
3+
4+
.PHONY: build run clean size
5+
.DEFAULT_GOAL := all
6+
7+
# Append cross-prefix for cross compilation
8+
# Remove or ignore for native builds
9+
CC ?= gcc
10+
SIZE ?= size
11+
# When called from the root Makefile, CROSS_PREFIX has already been added here
12+
ifeq (,$(findstring $(CROSS_PREFIX),$(CC)))
13+
CC := $(CROSS_PREFIX)$(CC)
14+
endif
15+
16+
ifeq (,$(findstring $(CROSS_PREFIX),$(SIZE)))
17+
SIZE := $(CROSS_PREFIX)$(SIZE)
18+
endif
19+
20+
# Part A:
21+
#
22+
# mldsa-native source and header files
23+
# Note: We exclude the fips202/ directory since we're providing our own
24+
MLD_SOURCE=$(wildcard \
25+
../../mldsa/*.c \
26+
../../mldsa/native/**/*.c \
27+
../../mldsa/native/**/**/*.c)
28+
29+
INC=-I../../mldsa/ -Icustom_fips202/
30+
31+
# Part B:
32+
#
33+
# Custom FIPS-202 implementation
34+
#
35+
# At present, this must be located in a directory named "fips202".
36+
# This limitation will be lifted in the future.
37+
FIPS202_SOURCE=custom_fips202/tiny_sha3/sha3.c
38+
39+
# Part C:
40+
#
41+
# Random number generator
42+
#
43+
# !!! WARNING !!!
44+
#
45+
# The randombytes() implementation used here is for TESTING ONLY.
46+
# You MUST NOT use this implementation outside of testing.
47+
#
48+
# !!! WARNING !!!
49+
RNG_SOURCE=$(wildcard test_only_rng/*.c)
50+
51+
# Part D:
52+
#
53+
# Your application source code
54+
APP_SOURCE=$(wildcard *.c)
55+
56+
ALL_SOURCE=$(MLD_SOURCE) $(FIPS202_SOURCE) $(RNG_SOURCE) $(APP_SOURCE)
57+
58+
BUILD_DIR=build
59+
BIN=test_binary
60+
61+
CFLAGS := \
62+
-Wall \
63+
-Wextra \
64+
-Werror \
65+
-Wmissing-prototypes \
66+
-Wshadow \
67+
-Wpointer-arith \
68+
-Wredundant-decls \
69+
-Wconversion \
70+
-Wsign-conversion \
71+
-Wno-long-long \
72+
-Wno-unknown-pragmas \
73+
-Wno-unused-command-line-argument \
74+
-fomit-frame-pointer \
75+
-std=c99 \
76+
-pedantic \
77+
-MMD \
78+
-O3 \
79+
$(CFLAGS)
80+
CFLAGS += -DMLD_CONFIG_FIPS202_CUSTOM_HEADER="\"fips202.h\""
81+
CFLAGS += -DMLD_CONFIG_FIPS202X4_CUSTOM_HEADER="\"fips202x4.h\""
82+
CFLAGS += -DMLD_CONFIG_NAMESPACE_PREFIX=mldsa
83+
84+
BINARY_NAME_FULL_44=$(BUILD_DIR)/$(BIN)44
85+
BINARY_NAME_FULL_65=$(BUILD_DIR)/$(BIN)65
86+
BINARY_NAME_FULL_87=$(BUILD_DIR)/$(BIN)87
87+
BINARIES_FULL=$(BINARY_NAME_FULL_44) $(BINARY_NAME_FULL_65) $(BINARY_NAME_FULL_87)
88+
89+
$(BINARY_NAME_FULL_44): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=44
90+
$(BINARY_NAME_FULL_65): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=65
91+
$(BINARY_NAME_FULL_87): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=87
92+
93+
$(BINARIES_FULL): $(ALL_SOURCE)
94+
echo "$@"
95+
mkdir -p $(BUILD_DIR)
96+
$(CC) $(CFLAGS) $(INC) $^ -o $@
97+
98+
all: build size
99+
100+
build: $(BINARIES_FULL)
101+
102+
run: $(BINARIES_FULL)
103+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_44)
104+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_65)
105+
$(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_87)
106+
107+
size: build
108+
@echo "=== Size info for $(BINARY_NAME_FULL_44) ==="
109+
@$(SIZE) $(BINARY_NAME_FULL_44)
110+
@echo "=== Size info for $(BINARY_NAME_FULL_65) ==="
111+
@$(SIZE) $(BINARY_NAME_FULL_65)
112+
@echo "=== Size info for $(BINARY_NAME_FULL_87) ==="
113+
@$(SIZE) $(BINARY_NAME_FULL_87)
114+
115+
clean:
116+
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)

0 commit comments

Comments
 (0)