-
Notifications
You must be signed in to change notification settings - Fork 26
Example: Add custom_backend #699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT | ||
|
|
||
| build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| # Copyright (c) The mldsa-native project authors | ||
| # SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT | ||
|
|
||
| .PHONY: build run clean | ||
| .DEFAULT_GOAL := all | ||
|
|
||
| CC ?= gcc | ||
|
|
||
| # Adjust CFLAGS if needed | ||
| CFLAGS := \ | ||
| -Wall \ | ||
| -Wextra \ | ||
| -Werror=unused-result \ | ||
| -Wpedantic \ | ||
| -Werror \ | ||
| -Wmissing-prototypes \ | ||
| -Wshadow \ | ||
| -Wpointer-arith \ | ||
| -Wredundant-decls \ | ||
| -Wconversion \ | ||
| -Wsign-conversion \ | ||
| -Wno-long-long \ | ||
| -Wno-unknown-pragmas \ | ||
| -Wno-unused-command-line-argument \ | ||
| -O3 \ | ||
| -fomit-frame-pointer \ | ||
| -std=c99 \ | ||
| -pedantic \ | ||
| -MMD \ | ||
| $(CFLAGS) | ||
|
|
||
| # If you want to use the native backends, the compiler needs to know about | ||
| # the target architecture. Here, we import the default host detection from | ||
| # mldsa-native's tests, but you can write your own or specialize accordingly. | ||
| AUTO ?= 1 | ||
| include auto.mk | ||
|
|
||
| # The following only concerns the cross-compilation tests. | ||
| # You can likely ignore the following for your application. | ||
| # | ||
| # Append cross-prefix for cross compilation | ||
| # When called from the root Makefile, CROSS_PREFIX has already been added here | ||
| ifeq (,$(findstring $(CROSS_PREFIX),$(CC))) | ||
| CC := $(CROSS_PREFIX)$(CC) | ||
| endif | ||
|
|
||
| # Part A: | ||
| # | ||
| # mldsa-native source and header files | ||
| # | ||
| # In this example, we compile the individual mldsa-native source files directly. | ||
| # Alternatively, you can compile the 'monobuild' source file mldsa_native.c. | ||
| # See examples/monolithic_build for that. | ||
| MLD_SOURCE=$(wildcard \ | ||
| mldsa_native/mldsa/src/*.c \ | ||
| mldsa_native/mldsa/src/**/*.c \ | ||
| mldsa_native/mldsa/src/**/**/*.c \ | ||
| mldsa_native/mldsa/src/**/**/**/*.c \ | ||
| mldsa_native/mldsa/src/**/**/**/**/*.c) | ||
|
|
||
| INC=-Imldsa_native -Imldsa_native/mldsa | ||
|
|
||
| # Part B: | ||
| # | ||
| # Random number generator | ||
| # | ||
| # !!! WARNING !!! | ||
| # | ||
| # The randombytes() implementation used here is for TESTING ONLY. | ||
| # You MUST NOT use this implementation outside of testing. | ||
| # | ||
| # !!! WARNING !!! | ||
| RNG_SOURCE=$(wildcard test_only_rng/*.c) | ||
|
|
||
| # Part C: | ||
| # | ||
| # Your application source code | ||
| APP_SOURCE=$(wildcard *.c) | ||
|
|
||
| ALL_SOURCE=$(MLD_SOURCE) $(RNG_SOURCE) $(APP_SOURCE) | ||
|
|
||
|
|
||
| # | ||
| # Configuration adjustments | ||
| # | ||
|
|
||
| # Pick custom config file | ||
| CFLAGS+=-DMLD_CONFIG_FILE="\"custom_config.h\"" | ||
|
|
||
| BUILD_DIR=build | ||
| BIN=test_binary | ||
|
|
||
| BINARY_NAME_FULL_44=$(BUILD_DIR)/$(BIN)44 | ||
| BINARY_NAME_FULL_65=$(BUILD_DIR)/$(BIN)65 | ||
| BINARY_NAME_FULL_87=$(BUILD_DIR)/$(BIN)87 | ||
| BINARIES_FULL=$(BINARY_NAME_FULL_44) $(BINARY_NAME_FULL_65) $(BINARY_NAME_FULL_87) | ||
|
|
||
| $(BINARY_NAME_FULL_44): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=44 | ||
| $(BINARY_NAME_FULL_65): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=65 | ||
| $(BINARY_NAME_FULL_87): CFLAGS += -DMLD_CONFIG_PARAMETER_SET=87 | ||
|
|
||
| $(BINARIES_FULL): $(ALL_SOURCE) | ||
| echo "$@" | ||
| mkdir -p $(BUILD_DIR) | ||
| $(CC) $(CFLAGS) $(INC) $^ -o $@ | ||
|
|
||
| all: build | ||
|
|
||
| build: $(BINARIES_FULL) | ||
|
|
||
| run: $(BINARIES_FULL) | ||
| $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_44) | ||
| $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_65) | ||
| $(EXEC_WRAPPER) ./$(BINARY_NAME_FULL_87) | ||
|
|
||
| clean: | ||
| rm -rf $(BUILD_DIR) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| [//]: # (SPDX-License-Identifier: CC-BY-4.0) | ||
|
|
||
| # Using a custom configuration and FIPS-202 backend | ||
|
|
||
| This directory contains a minimal example for how to use mldsa-native as a code package, with a custom FIPS-202 | ||
| backend and a custom configuration. We use [^tiny_sha3] as an example. | ||
|
|
||
| ## Components | ||
|
|
||
| An application using mldsa-native with a custom FIPS-202 backend and custom configuration needs the following: | ||
|
|
||
| 1. Arithmetic part of the mldsa-native source tree: [`mldsa/src/`](../../mldsa/src). In this example, we disable arithmetic | ||
| backends, hence it is safe to remove the entire `native` subfolder. | ||
| 2. A secure pseudo random number generator, implementing [`randombytes.h`](../../mldsa/src/randombytes.h). **WARNING:** The | ||
| `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation outside of testing. | ||
| 3. FIPS-202 part of the mldsa-native source tree, [`fips202/`](../../mldsa/src/fips202). If you only want to use your backend, | ||
| you can remove all existing backends; that's what this example does. | ||
| 4. A custom FIPS-202 backend. In this example, the backend file is | ||
| [custom.h](mldsa_native/mldsa/src/fips202/native/custom/custom.h), wrapping | ||
| [sha3.c](mldsa_native/mldsa/src/fips202/native/custom/src/sha3.c) and setting `MLD_USE_FIPS202_X1_NATIVE` to indicate that we | ||
| replace 1-fold Keccak-F1600. | ||
| 5. Either modify the existing [config.h](mldsa_native/mldsa/src/config.h), or register a new config. In this example, we add | ||
| a new config [custom_config.h](mldsa_native/custom_config.h) and register it from the command line for | ||
| `-DMLD_CONFIG_FILE="custom_config.h"` -- no further changes to the build are needed. For the sake of | ||
| demonstration, we set a custom namespace. We set `MLD_CONFIG_FIPS202_BACKEND_FILE` to point to our custom FIPS-202 | ||
| backend, but leave `MLD_CONFIG_USE_NATIVE_BACKEND_ARITH` undefined to indicate that we wish to use the C backend. | ||
|
|
||
| ## Note | ||
|
|
||
| The tiny_sha3 code uses a byte-reversed presentation of the Keccakf1600 state for big-endian targets. Since | ||
| mldsa-native's FIPS202 frontend assumes a standard presentation, the corresponding byte-reversal in | ||
| [sha3.c](mldsa_native/mldsa/src/fips202/native/custom/src/sha3.c) is removed. | ||
|
|
||
| ## Usage | ||
|
|
||
| Build this example with `make build`, run with `make run`. | ||
|
|
||
| <!--- bibliography ---> | ||
| [^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../test/mk/auto.mk |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../basic/expected_signatures.h |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| /* | ||
| * Copyright (c) The mldsa-native project authors | ||
| * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT | ||
| */ | ||
|
|
||
| #include <stdint.h> | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <string.h> | ||
|
|
||
| /* Import public mldsa-native API | ||
| * | ||
| * This requires specifying the parameter set and namespace prefix | ||
| * used for the build. | ||
| */ | ||
| #define MLD_CONFIG_API_PARAMETER_SET MLD_CONFIG_PARAMETER_SET | ||
| #define MLD_CONFIG_API_NAMESPACE_PREFIX CUSTOM_TINY_SHA3 | ||
| #include <mldsa_native.h> | ||
| #include "expected_signatures.h" | ||
| #include "test_only_rng/notrandombytes.h" | ||
|
|
||
| #define CHECK(x) \ | ||
| do \ | ||
| { \ | ||
| int rc; \ | ||
| rc = (x); \ | ||
| if (!rc) \ | ||
| { \ | ||
| fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \ | ||
| return 1; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| #define TEST_MSG \ | ||
| "This is a test message for ML-DSA digital signature algorithm!" | ||
| #define TEST_MSG_LEN (sizeof(TEST_MSG) - 1) | ||
|
|
||
| #define TEST_CTX "test_context_123" | ||
| #define TEST_CTX_LEN (sizeof(TEST_CTX) - 1) | ||
|
|
||
| int main(void) | ||
| { | ||
| const char test_msg[] = TEST_MSG; | ||
| const char test_ctx[] = TEST_CTX; | ||
|
|
||
| uint8_t pk[CRYPTO_PUBLICKEYBYTES]; | ||
| uint8_t sk[CRYPTO_SECRETKEYBYTES]; | ||
| uint8_t sig[CRYPTO_BYTES]; | ||
| uint8_t sm[TEST_MSG_LEN + CRYPTO_BYTES]; /* signed message buffer */ | ||
| uint8_t m2[TEST_MSG_LEN + CRYPTO_BYTES]; /* recovered message buffer */ | ||
| size_t siglen; | ||
| size_t smlen; | ||
| size_t mlen; | ||
|
|
||
| /* WARNING: Test-only | ||
| * Normally, you would want to seed a PRNG with trustworthy entropy here. */ | ||
| randombytes_reset(); | ||
|
|
||
| printf("ML-DSA-%d Custom Backend Example\n", MLD_CONFIG_PARAMETER_SET); | ||
| printf("======================\n\n"); | ||
|
|
||
| printf("Message: %s\n", test_msg); | ||
| printf("Context: %s\n\n", test_ctx); | ||
|
|
||
| printf("Generating keypair ... "); | ||
|
|
||
| /* Alice generates a public/private key pair */ | ||
| CHECK(crypto_sign_keypair(pk, sk) == 0); | ||
|
|
||
| printf("DONE\n"); | ||
| printf("Signing message... "); | ||
|
|
||
| /* Alice signs the message */ | ||
| CHECK(crypto_sign_signature(sig, &siglen, (const uint8_t *)test_msg, | ||
| TEST_MSG_LEN, (const uint8_t *)test_ctx, | ||
| TEST_CTX_LEN, sk) == 0); | ||
|
|
||
| printf("DONE\n"); | ||
| printf("Verifying signature... "); | ||
|
|
||
| /* Bob verifies Alice's signature */ | ||
| CHECK(crypto_sign_verify(sig, siglen, (const uint8_t *)test_msg, TEST_MSG_LEN, | ||
| (const uint8_t *)test_ctx, TEST_CTX_LEN, pk) == 0); | ||
|
|
||
| printf("DONE\n"); | ||
| printf("Creating signed message... "); | ||
|
|
||
| /* Alternative API: Create a signed message (signature + message combined) */ | ||
| CHECK(crypto_sign(sm, &smlen, (const uint8_t *)test_msg, TEST_MSG_LEN, | ||
| (const uint8_t *)test_ctx, TEST_CTX_LEN, sk) == 0); | ||
|
|
||
| printf("DONE\n"); | ||
| printf("Opening signed message... "); | ||
|
|
||
| /* Bob opens the signed message to recover the original message */ | ||
| CHECK(crypto_sign_open(m2, &mlen, sm, smlen, (const uint8_t *)test_ctx, | ||
| TEST_CTX_LEN, pk) == 0); | ||
|
|
||
| printf("DONE\n"); | ||
| printf("Compare messages... "); | ||
|
|
||
| /* Verify the recovered message matches the original */ | ||
| CHECK(mlen == TEST_MSG_LEN); | ||
| CHECK(memcmp(test_msg, m2, TEST_MSG_LEN) == 0); | ||
|
|
||
| printf("DONE\n\n"); | ||
|
|
||
| printf("Results:\n"); | ||
| printf("--------\n"); | ||
| printf("Public key size: %d bytes\n", CRYPTO_PUBLICKEYBYTES); | ||
| printf("Secret key size: %d bytes\n", CRYPTO_SECRETKEYBYTES); | ||
| printf("Signature size: %d bytes\n", CRYPTO_BYTES); | ||
| printf("Message length: %lu bytes\n", (unsigned long)TEST_MSG_LEN); | ||
| printf("Signature length: %lu bytes\n", (unsigned long)siglen); | ||
| printf("Signed msg length: %lu bytes\n", (unsigned long)smlen); | ||
|
|
||
| #if !defined(MLD_CONFIG_KEYGEN_PCT) | ||
| /* Check against expected signature to make sure that | ||
| * we integrated the library correctly */ | ||
| printf("Checking deterministic signature... "); | ||
| { | ||
| /* Compare the generated signature directly against the expected signature | ||
| */ | ||
| CHECK(siglen == sizeof(expected_signature)); | ||
| CHECK(memcmp(sig, expected_signature, siglen) == 0); | ||
| } | ||
| printf("DONE\n"); | ||
| #else /* !MLD_CONFIG_KEYGEN_PCT */ | ||
| printf( | ||
| "[WARNING] Skipping KAT test since PCT is enabled and modifies PRNG\n"); | ||
| #endif /* MLD_CONFIG_KEYGEN_PCT */ | ||
|
|
||
| printf("Signature verification completed successfully!\n"); | ||
|
|
||
| printf("\nAll tests passed! ML-DSA signature verification successful.\n"); | ||
| return 0; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.