diff --git a/BIBLIOGRAPHY.md b/BIBLIOGRAPHY.md index 91d7a9a23..6975da8d5 100644 --- a/BIBLIOGRAPHY.md +++ b/BIBLIOGRAPHY.md @@ -24,6 +24,7 @@ source code and documentation. * URL: https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements * Referenced from: - [examples/basic_deterministic/mldsa_native/custom_no_randomized_config.h](examples/basic_deterministic/mldsa_native/custom_no_randomized_config.h) + - [examples/custom_backend/mldsa_native/custom_config.h](examples/custom_backend/mldsa_native/custom_config.h) - [examples/monolithic_build/config_44.h](examples/monolithic_build/config_44.h) - [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h) - [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h) @@ -69,6 +70,7 @@ source code and documentation. * Referenced from: - [README.md](README.md) - [examples/basic_deterministic/mldsa_native/custom_no_randomized_config.h](examples/basic_deterministic/mldsa_native/custom_no_randomized_config.h) + - [examples/custom_backend/mldsa_native/custom_config.h](examples/custom_backend/mldsa_native/custom_config.h) - [examples/monolithic_build/config_44.h](examples/monolithic_build/config_44.h) - [examples/monolithic_build/config_65.h](examples/monolithic_build/config_65.h) - [examples/monolithic_build/config_87.h](examples/monolithic_build/config_87.h) @@ -363,6 +365,7 @@ source code and documentation. - [examples/bring_your_own_fips202/README.md](examples/bring_your_own_fips202/README.md) - [examples/bring_your_own_fips202_static/README.md](examples/bring_your_own_fips202_static/README.md) - [examples/bring_your_own_fips202_static/custom_fips202/README.md](examples/bring_your_own_fips202_static/custom_fips202/README.md) + - [examples/custom_backend/README.md](examples/custom_backend/README.md) ### `tweetfips` diff --git a/Makefile b/Makefile index 55dc7f739..ffa0757cf 100644 --- a/Makefile +++ b/Makefile @@ -223,3 +223,4 @@ clean: -make clean -C examples/monolithic_build_multilevel >/dev/null -make clean -C examples/monolithic_build_native >/dev/null -make clean -C examples/monolithic_build_multilevel_native >/dev/null + -make clean -C examples/custom_backend >/dev/null diff --git a/examples/custom_backend/.gitignore b/examples/custom_backend/.gitignore new file mode 100644 index 000000000..eb98a94f1 --- /dev/null +++ b/examples/custom_backend/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +build diff --git a/examples/custom_backend/Makefile b/examples/custom_backend/Makefile new file mode 100644 index 000000000..2bf055cea --- /dev/null +++ b/examples/custom_backend/Makefile @@ -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) diff --git a/examples/custom_backend/README.md b/examples/custom_backend/README.md new file mode 100644 index 000000000..2e7858f5a --- /dev/null +++ b/examples/custom_backend/README.md @@ -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`. + + +[^tiny_sha3]: Markku-Juhani O. Saarinen: tiny_sha3, [https://github.com/mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3) diff --git a/examples/custom_backend/auto.mk b/examples/custom_backend/auto.mk new file mode 120000 index 000000000..ce5c161cb --- /dev/null +++ b/examples/custom_backend/auto.mk @@ -0,0 +1 @@ +../../test/mk/auto.mk \ No newline at end of file diff --git a/examples/custom_backend/expected_signatures.h b/examples/custom_backend/expected_signatures.h new file mode 120000 index 000000000..694d65628 --- /dev/null +++ b/examples/custom_backend/expected_signatures.h @@ -0,0 +1 @@ +../basic/expected_signatures.h \ No newline at end of file diff --git a/examples/custom_backend/main.c b/examples/custom_backend/main.c new file mode 100644 index 000000000..46a7269f8 --- /dev/null +++ b/examples/custom_backend/main.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#include +#include +#include +#include + +/* 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 +#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; +} diff --git a/examples/custom_backend/mldsa_native/custom_config.h b/examples/custom_backend/mldsa_native/custom_config.h new file mode 100644 index 000000000..bb28b363e --- /dev/null +++ b/examples/custom_backend/mldsa_native/custom_config.h @@ -0,0 +1,568 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +/* References + * ========== + * + * - [FIPS140_3_IG] + * Implementation Guidance for FIPS 140-3 and the Cryptographic Module + * Validation Program + * National Institute of Standards and Technology + * https://csrc.nist.gov/projects/cryptographic-module-validation-program/fips-140-3-ig-announcements + * + * - [FIPS204] + * FIPS 204 Module-Lattice-Based Digital Signature Standard + * National Institute of Standards and Technology + * https://csrc.nist.gov/pubs/fips/204/final + */ + +/* + * WARNING: This file is auto-generated from scripts/autogen + * in the mldsa-native repository. + * Do not modify it directly. + */ + +/* + * Test configuration: Custom backend config with tiny SHA3 + * + * This configuration differs from the default mldsa/src/config.h in the + * following places: + * - MLD_CONFIG_USE_NATIVE_BACKEND_ARITH + * - MLD_CONFIG_NAMESPACE_PREFIX + * - MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 + * - MLD_CONFIG_FIPS202_BACKEND_FILE + */ + + +#ifndef MLD_CONFIG_H +#define MLD_CONFIG_H + +/****************************************************************************** + * Name: MLD_CONFIG_PARAMETER_SET + * + * Description: Specifies the parameter set for ML-DSA + * - MLD_CONFIG_PARAMETER_SET=44 corresponds to ML-DSA-44 + * - MLD_CONFIG_PARAMETER_SET=65 corresponds to ML-DSA-65 + * - MLD_CONFIG_PARAMETER_SET=87 corresponds to ML-DSA-87 + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* This is set on the command line */ +#ifndef MLD_CONFIG_PARAMETER_SET +#define MLD_CONFIG_PARAMETER_SET \ + 44 /* Change this for different security strengths */ +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_NAMESPACE_PREFIX + * + * Description: The prefix to use to namespace global symbols from mldsa/. + * + * In a multi-level build (that is, if either + * - MLD_CONFIG_MULTILEVEL_WITH_SHARED, or + * - MLD_CONFIG_MULTILEVEL_NO_SHARED, + * are set, level-dependent symbols will additionally be prefixed + * with the parameter set (44/65/87). + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_NAMESPACE_PREFIX CUSTOM_TINY_SHA3 + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_WITH_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, all MLD_CONFIG_PARAMETER_SET-independent + * code will be included in the build, including code needed only + * for other parameter sets. + * + * Example: TODO: add example + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_WITH_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_MULTILEVEL_NO_SHARED + * + * Description: This is for multi-level builds of mldsa-native only. If you + * need only a single parameter set, keep this unset. + * + * If this is set, no MLD_CONFIG_PARAMETER_SET-independent code + * will be included in the build. + * + * To build mldsa-native with support for all parameter sets, + * build it three times -- once per parameter set -- and set the + * option MLD_CONFIG_MULTILEVEL_WITH_SHARED for exactly one of + * them, and MLD_CONFIG_MULTILEVEL_NO_SHARED for the others. + * + * See examples/multilevel_build_mldsa for an example. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* #define MLD_CONFIG_MULTILEVEL_NO_SHARED */ + +/****************************************************************************** + * Name: MLD_CONFIG_FILE + * + * Description: If defined, this is a header that will be included instead + * of the default configuration file mldsa/src/config.h. + * + * When you need to build mldsa-native in multiple configurations, + * using varying MLD_CONFIG_FILE can be more convenient + * then configuring everything through CFLAGS. + * + * To use, MLD_CONFIG_FILE _must_ be defined prior + * to the inclusion of any mldsa-native headers. For example, + * it can be set by passing `-DMLD_CONFIG_FILE="..."` + * on the command line. + * + *****************************************************************************/ +/* No need to set this -- we _are_ already in a custom config */ +/* #define MLD_CONFIG_FILE "config.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_USE_NATIVE_BACKEND_ARITH + * + * Description: Determines whether an native arithmetic backend should be used. + * + * The arithmetic backend covers performance critical functions + * such as the number-theoretic transform (NTT). + * + * If this option is unset, the C backend will be used. + * + * If this option is set, the arithmetic backend to be use is + * determined by MLD_CONFIG_ARITH_BACKEND_FILE: If the latter is + * unset, the default backend for your the target architecture + * will be used. If set, it must be the name of a backend metadata + * file. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +/* No native arithmetic backend */ +/* #define MLD_CONFIG_USE_NATIVE_BACKEND_ARITH */ + +/****************************************************************************** + * Name: MLD_CONFIG_ARITH_BACKEND_FILE + * + * Description: The arithmetic backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is unset, this option + * is ignored. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_ARITH is set, this option must + * either be undefined or the filename of an arithmetic backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_ARITH) && \ + !defined(MLD_CONFIG_ARITH_BACKEND_FILE) +#define MLD_CONFIG_ARITH_BACKEND_FILE "native/meta.h" +#endif + +/****************************************************************************** + * Name: MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 + * + * Description: Determines whether an native FIPS202 backend should be used. + * + * The FIPS202 backend covers 1x/2x/4x-fold Keccak-f1600, which is + * the performance bottleneck of SHA3 and SHAKE. + * + * If this option is unset, the C backend will be used. + * + * If this option is set, the FIPS202 backend to be use is + * determined by MLD_CONFIG_FIPS202_BACKEND_FILE: If the latter is + * unset, the default backend for your the target architecture + * will be used. If set, it must be the name of a backend metadata + * file. + * + * This can also be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_BACKEND_FILE + * + * Description: The FIPS-202 backend to use. + * + * If MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 is set, this option + * must either be undefined or the filename of a FIPS202 backend. + * If unset, the default backend will be used. + * + * This can be set using CFLAGS. + * + *****************************************************************************/ +#define MLD_CONFIG_FIPS202_BACKEND_FILE "fips202/native/custom/custom.h" +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/src/fips202/fips202.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_FIPS202X4_CUSTOM_HEADER + * + * Description: Custom header to use for FIPS-202-X4 + * + * This should only be set if you intend to use a custom + * FIPS-202 implementation, different from the one shipped + * with mldsa-native. + * + * If set, it must be the name of a file serving as the + * replacement for mldsa/src/fips202/fips202x4.h, and exposing + * the same API (see FIPS202.md). + * + *****************************************************************************/ +/* #define MLD_CONFIG_FIPS202X4_CUSTOM_HEADER "SOME_FILE.h" */ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_ZEROIZE + * + * Description: In compliance with @[FIPS204, Section 3.6.3], mldsa-native, + * zeroizes intermediate stack buffers before returning from + * function calls. + * + * Set this option and define `mld_zeroize_native` if you want to + * use a custom method to zeroize intermediate stack buffers. + * The default implementation uses SecureZeroMemory on Windows + * and a memset + compiler barrier otherwise. If neither of those + * is available on the target platform, compilation will fail, + * and you will need to use MLD_CONFIG_CUSTOM_ZEROIZE to provide + * a custom implementation of `mld_zeroize_native()`. + * + * WARNING: + * The explicit stack zeroization conducted by mldsa-native + * reduces the likelihood of data leaking on the stack, but + * does not eliminate it! The C standard makes no guarantee about + * where a compiler allocates structures and whether/where it makes + * copies of them. Also, in addition to entire structures, there + * may also be potentially exploitable leakage of individual values + * on the stack. + * + * If you need bullet-proof zeroization of the stack, you need to + * consider additional measures instead of what this feature + * provides. In this case, you can set mld_zeroize_native to a + * no-op. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_ZEROIZE + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_zeroize_native(void *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMCPY + * + * Description: Set this option and define `mld_memcpy` if you want to + * use a custom method to copy memory instead of the standard + * library memcpy function. + * + * The custom implementation must have the same signature and + * behavior as the standard memcpy function: + * void *mld_memcpy(void *dest, const void *src, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMCPY + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memcpy(void *dest, const void *src, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_MEMSET + * + * Description: Set this option and define `mld_memset` if you want to + * use a custom method to set memory instead of the standard + * library memset function. + * + * The custom implementation must have the same signature and + * behavior as the standard memset function: + * void *mld_memset(void *s, int c, size_t n) + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_MEMSET + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void *mld_memset(void *s, int c, size_t n) + { + ... your implementation ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_RANDOMBYTES + * + * Description: mldsa-native does not provide a secure randombytes + * implementation. Such an implementation has to provided by the + * consumer. + * + * If this option is not set, mldsa-native expects a function + * void randombytes(uint8_t *out, size_t outlen). + * + * Set this option and define `mld_randombytes` if you want to + * use a custom method to sample randombytes with a different name + * or signature. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_RANDOMBYTES + #if !defined(__ASSEMBLER__) + #include + #include "sys.h" + static MLD_INLINE void mld_randombytes(uint8_t *ptr, size_t len) + { + ... your implementation ... + } + #endif +*/ + + +/****************************************************************************** + * Name: MLD_CONFIG_CUSTOM_CAPABILITY_FUNC + * + * Description: mldsa-native backends may rely on specific hardware features. + * Those backends will only be included in an mldsa-native build + * if support for the respective features is enabled at + * compile-time. However, when building for a heteroneous set + * of CPUs to run the resulting binary/library on, feature + * detection at _runtime_ is needed to decided whether a backend + * can be used or not. + * + * Set this option and define `mld_sys_check_capability` if you + * want to use a custom method to dispatch between implementations. + * + * If this option is not set, mldsa-native uses compile-time + * feature detection only to decide which backend to use. + * + * If you compile mldsa-native on a system with different + * capabilities than the system that the resulting binary/library + * will be run on, you must use this option. + * + *****************************************************************************/ +/* #define MLD_CONFIG_CUSTOM_CAPABILITY_FUNC + static MLD_INLINE int mld_sys_check_capability(mld_sys_cap cap) + { + ... your implementation ... + } +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_RANDOMIZED_API + * + * Description: If this option is set, mldsa-native will be built without the + * randomized API functions (crypto_sign_keypair, + * crypto_sign, crypto_sign_signature, and + * crypto_sign_signature_extmu). + * This allows users to build mldsa-native without providing a + * randombytes() implementation if they only need the + * internal deterministic API + * (crypto_sign_keypair_internal, crypto_sign_signature_internal). + * + * NOTE: This option is incompatible with MLD_CONFIG_KEYGEN_PCT + * as the current PCT implementation requires + * crypto_sign_signature(). + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_RANDOMIZED_API */ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT + * + * Description: Compliance with @[FIPS140_3_IG, p.87] requires a + * Pairwise Consistency Test (PCT) to be carried out on a freshly + * generated keypair before it can be exported. + * + * Set this option if such a check should be implemented. + * In this case, crypto_sign_keypair_internal and + * crypto_sign_keypair will return a non-zero error code if the + * PCT failed. + * + * NOTE: This feature will drastically lower the performance of + * key generation. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT */ + +/****************************************************************************** + * Name: MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + * + * Description: If this option is set, the user must provide a runtime + * function `static inline int mld_break_pct() { ... }` to + * indicate whether the PCT should be made fail. + * + * This option only has an effect if MLD_CONFIG_KEYGEN_PCT is set. + * + *****************************************************************************/ +/* #define MLD_CONFIG_KEYGEN_PCT_BREAKAGE_TEST + #if !defined(__ASSEMBLER__) + #include "sys.h" + static MLD_INLINE int mld_break_pct(void) + { + ... return 0/1 depending on whether PCT should be broken ... + } + #endif +*/ + +/****************************************************************************** + * Name: MLD_CONFIG_INTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of internal API. + * + * The primary use case for this option are single-CU builds, + * in which case this option can be set to `static`. + * + *****************************************************************************/ +/* #define MLD_CONFIG_INTERNAL_API_QUALIFIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_EXTERNAL_API_QUALIFIER + * + * Description: If set, this option provides an additional function + * qualifier to be added to declarations of mldsa-native's + * public API. + * + * The primary use case for this option are single-CU builds + * where the public API exposed by mldsa-native is wrapped by + * another API in the consuming application. In this case, + * even mldsa-native's public API can be marked `static`. + * + *****************************************************************************/ +/* #define MLD_CONFIG_EXTERNAL_API_QUALIFIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_CT_TESTING_ENABLED + * + * Description: If set, mldsa-native annotates data as secret / public using + * valgrind's annotations VALGRIND_MAKE_MEM_UNDEFINED and + * VALGRIND_MAKE_MEM_DEFINED, enabling various checks for secret- + * dependent control flow of variable time execution (depending + * on the exact version of valgrind installed). + * + *****************************************************************************/ +/* #define MLD_CONFIG_CT_TESTING_ENABLED */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly. + * + * By default, inline assembly is used to implement value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + * Inline assembly is also used to implement a secure zeroization + * function on non-Windows platforms. If this option is set and + * the target platform is not Windows, you MUST set + * MLD_CONFIG_CUSTOM_ZEROIZE and provide a custom zeroization + * function. + * + * If this option is set, MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202 and + * and MLD_CONFIG_USE_NATIVE_BACKEND_ARITH will be ignored, and no + * native backends will be used. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM */ + +/****************************************************************************** + * Name: MLD_CONFIG_NO_ASM_VALUE_BARRIER + * + * Description: If this option is set, mldsa-native will be built without + * use of native code or inline assembly for value barriers. + * + * By default, inline assembly (if available) is used to implement + * value barriers. + * Without inline assembly, mldsa-native will use a global volatile + * 'opt blocker' instead; see ct.h. + * + *****************************************************************************/ +/* #define MLD_CONFIG_NO_ASM_VALUE_BARRIER */ + +/****************************************************************************** + * Name: MLD_CONFIG_SERIAL_FIPS202_ONLY + * + * Description: Set this to use a FIPS202 implementation with global state + * that supports only one active Keccak computation at a time + * (e.g. some hardware accelerators). + * + * If this option is set, ML-DSA will use FIPS202 operations + * serially, ensuring that only one SHAKE context is active + * at any given time. + * + * This allows offloading Keccak computations to a hardware + * accelerator that holds only a single Keccak state locally, + * rather than requiring support for multiple concurrent + * Keccak states. + * + * NOTE: Depending on the target CPU, this may reduce + * performance when using software FIPS202 implementations. + * Only enable this when you have to. + * + *****************************************************************************/ +/* #define MLD_CONFIG_SERIAL_FIPS202_ONLY */ + +/************************* Config internals ********************************/ + +/* Default namespace + * + * Don't change this. If you need a different namespace, re-define + * MLD_CONFIG_NAMESPACE_PREFIX above instead, and remove the following. + * + * The default MLDSA namespace is + * + * PQCP_MLDSA_NATIVE_MLDSA_ + * + * e.g., PQCP_MLDSA_NATIVE_MLDSA44_ + */ + +#if MLD_CONFIG_PARAMETER_SET == 44 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA44 +#elif MLD_CONFIG_PARAMETER_SET == 65 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA65 +#elif MLD_CONFIG_PARAMETER_SET == 87 +#define MLD_DEFAULT_NAMESPACE_PREFIX PQCP_MLDSA_NATIVE_MLDSA87 +#endif + +#endif /* !MLD_CONFIG_H */ diff --git a/examples/custom_backend/mldsa_native/mldsa/mldsa_native.h b/examples/custom_backend/mldsa_native/mldsa/mldsa_native.h new file mode 120000 index 000000000..771223a87 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/mldsa_native.h @@ -0,0 +1 @@ +../../../../mldsa/mldsa_native.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/cbmc.h b/examples/custom_backend/mldsa_native/mldsa/src/cbmc.h new file mode 120000 index 000000000..3bb0397f4 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/cbmc.h @@ -0,0 +1 @@ +../../../../../mldsa/src/cbmc.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/common.h b/examples/custom_backend/mldsa_native/mldsa/src/common.h new file mode 120000 index 000000000..13ce091e1 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/common.h @@ -0,0 +1 @@ +../../../../../mldsa/src/common.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/config.h b/examples/custom_backend/mldsa_native/mldsa/src/config.h new file mode 120000 index 000000000..0082048af --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/config.h @@ -0,0 +1 @@ +../../../../../mldsa/src/config.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/ct.c b/examples/custom_backend/mldsa_native/mldsa/src/ct.c new file mode 120000 index 000000000..de3a51984 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/ct.c @@ -0,0 +1 @@ +../../../../../mldsa/src/ct.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/ct.h b/examples/custom_backend/mldsa_native/mldsa/src/ct.h new file mode 120000 index 000000000..a0baf328e --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/ct.h @@ -0,0 +1 @@ +../../../../../mldsa/src/ct.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/debug.c b/examples/custom_backend/mldsa_native/mldsa/src/debug.c new file mode 120000 index 000000000..ff35fcf68 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/debug.c @@ -0,0 +1 @@ +../../../../../mldsa/src/debug.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/debug.h b/examples/custom_backend/mldsa_native/mldsa/src/debug.h new file mode 120000 index 000000000..cf59a6ce1 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/debug.h @@ -0,0 +1 @@ +../../../../../mldsa/src/debug.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202.c b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202.c new file mode 120000 index 000000000..06d7b07be --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202.c @@ -0,0 +1 @@ +../../../../../../mldsa/src/fips202/fips202.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202.h b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202.h new file mode 120000 index 000000000..b564c1828 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202.h @@ -0,0 +1 @@ +../../../../../../mldsa/src/fips202/fips202.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202x4.c b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202x4.c new file mode 120000 index 000000000..21e6e6a49 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202x4.c @@ -0,0 +1 @@ +../../../../../../mldsa/src/fips202/fips202x4.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202x4.h b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202x4.h new file mode 120000 index 000000000..60f666a21 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/fips202x4.h @@ -0,0 +1 @@ +../../../../../../mldsa/src/fips202/fips202x4.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/keccakf1600.c b/examples/custom_backend/mldsa_native/mldsa/src/fips202/keccakf1600.c new file mode 120000 index 000000000..493a4b368 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/keccakf1600.c @@ -0,0 +1 @@ +../../../../../../mldsa/src/fips202/keccakf1600.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/keccakf1600.h b/examples/custom_backend/mldsa_native/mldsa/src/fips202/keccakf1600.h new file mode 120000 index 000000000..9fe1baac4 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/keccakf1600.h @@ -0,0 +1 @@ +../../../../../../mldsa/src/fips202/keccakf1600.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/api.h b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/api.h new file mode 120000 index 000000000..4aa982866 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/api.h @@ -0,0 +1 @@ +../../../../../../../mldsa/src/fips202/native/api.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/custom.h b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/custom.h new file mode 100644 index 000000000..afd8a3fd3 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/custom.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) The mldsa-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ + +#if !defined(MLD_FIPS202_CUSTOM_TINY_SHA3_H) +#define MLD_FIPS202_CUSTOM_TINY_SHA3_H + +#if !defined(__ASSEMBLER__) +#include "../api.h" +#include "src/sha3.h" +/* Replace (single) Keccak-F1600 by tiny-SHA3's */ +#define MLD_USE_FIPS202_X1_NATIVE +static MLD_INLINE int mld_keccak_f1600_x1_native(uint64_t *state) +{ + tiny_sha3_keccakf(state); + + return MLD_NATIVE_FUNC_SUCCESS; +} +#endif /* !__ASSEMBLER__ */ + +#endif /* !MLD_FIPS202_CUSTOM_TINY_SHA3_H */ diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/LICENSE b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/LICENSE new file mode 100644 index 000000000..35741e52a --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/LICENSE @@ -0,0 +1,23 @@ +[//]: # (SPDX-License-Identifier: CC-BY-4.0) + +The MIT License (MIT) + +Copyright (c) 2015 Markku-Juhani O. Saarinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/README.md b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/README.md new file mode 100644 index 000000000..38785e462 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/README.md @@ -0,0 +1,63 @@ +[//]: # (SPDX-License-Identifier: MIT) + +# tiny_sha3 +Very small, readable implementation of the FIPS 202 and SHA3 hash function. +Public domain. + +### Updated 27-Dec-15: + +Added SHAKE128 and SHAKE256 code and test vectors. The code can actually do +a XOF of arbitrary size (like "SHAKE512"). + + +### Updated 03-Sep-15: + +Made the implementation portable. The API is now pretty much the +same that OpenSSL uses. + + +### Updated 07-Aug-15: + +Now that SHA3 spec is out, I've updated the package to match with the +new padding rules. There is literally one line difference between +Keccak 3.0 and SHA-3 implementations: + +``` + temp[inlen++] = 0x06; // XXX Padding Changed from Keccak 3.0 +``` + +The 0x06 constant there used to be 0x01. But this of course totally +breaks compatibility and test vectors had to be revised. + +SHA-3 Spec: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + +Cheers, +- markku + + +### Original README.TXT from 19-Nov-11: + +Hi. + +The SHA-3 competition is nearing it's end and I would personally like +to support Keccak as the winner. I have a PhD in hash function cryptanalysis +so don't take my word for it, go ahead and look into the code ! + +Since I couldn't find a *compact* and/or *readable* implementation of Keccak +anywhere, here's one I cooked up as a service to the curious. + +This implementation is intended for study of the algorithm, not for +production use. + +The code works correctly on 64-bit little-endian platforms with gcc. +Like your Linux box. The main.c module contains self-tests for all +officially supported hash sizes. + +If you're looking for production code, the official multi-megabyte package +covers everything you could possibly need and too much much more: +http://keccak.noekeon.org/ + +Cheers, +- Markku 19-Nov-11 + +Dr. Markku-Juhani O. Saarinen diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/sha3.c b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/sha3.c new file mode 100644 index 000000000..c7e0910f0 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/sha3.c @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: MIT + * + * sha3.c + * 19-Nov-11 Markku-Juhani O. Saarinen */ + +/* Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" */ +/* Revised 03-Sep-15 for portability + OpenSSL - style API */ + +#include "sha3.h" + +/* update the state with given number of rounds */ + +void tiny_sha3_keccakf(uint64_t st[25]) +{ + /* constants */ + const uint64_t keccakf_rndc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008}; + const int keccakf_rotc[24] = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44}; + const int keccakf_piln[24] = {10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1}; + + /* variables */ + int i, j, r; + uint64_t t, bc[5]; + + /* NOTE: + * This is present in the tiny_sha3 implementation because it uses + * a byte-reversed presentation of the Keccakf1600 state for big endian + * targets. mldsa-native uses the standard presentation, hence we don't + * the reversal here. */ + /* #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ */ + /* uint8_t *v; */ + + /* /\* endianness conversion. this is redundant on little-endian targets *\/ + */ + /* for (i = 0; i < 25; i++) */ + /* { */ + /* v = (uint8_t *)&st[i]; */ + /* st[i] = ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) | */ + /* (((uint64_t)v[2]) << 16) | (((uint64_t)v[3]) << 24) | */ + /* (((uint64_t)v[4]) << 32) | (((uint64_t)v[5]) << 40) | */ + /* (((uint64_t)v[6]) << 48) | (((uint64_t)v[7]) << 56); */ + /* } */ + /* #endif */ + + /* actual iteration */ + for (r = 0; r < KECCAKF_ROUNDS; r++) + { + /* Theta */ + for (i = 0; i < 5; i++) + { + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + } + + for (i = 0; i < 5; i++) + { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + { + st[j + i] ^= t; + } + } + + /* Rho Pi */ + t = st[1]; + for (i = 0; i < 24; i++) + { + j = keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, keccakf_rotc[i]); + t = bc[0]; + } + + /* Chi */ + for (j = 0; j < 25; j += 5) + { + for (i = 0; i < 5; i++) + { + bc[i] = st[j + i]; + } + for (i = 0; i < 5; i++) + { + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + } + + /* Iota */ + st[0] ^= keccakf_rndc[r]; + } + /* NOTE: + * This is present in the tiny_sha3 implementation because it uses + * a byte-reversed presentation of the Keccakf1600 state for big endian + * targets. mldsa-native uses the standard presentation, hence we don't + * the reversal here. */ + /* #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ */ + /* /\* endianness conversion. this is redundant on little-endian targets *\/ + */ + /* for (i = 0; i < 25; i++) */ + /* { */ + /* v = (uint8_t *)&st[i]; */ + /* t = st[i]; */ + /* v[0] = t & 0xFF; */ + /* v[1] = (t >> 8) & 0xFF; */ + /* v[2] = (t >> 16) & 0xFF; */ + /* v[3] = (t >> 24) & 0xFF; */ + /* v[4] = (t >> 32) & 0xFF; */ + /* v[5] = (t >> 40) & 0xFF; */ + /* v[6] = (t >> 48) & 0xFF; */ + /* v[7] = (t >> 56) & 0xFF; */ + /* } */ + /* #endif */ +} + +/* Initialize the context for SHA3 */ + +int tiny_sha3_init(sha3_ctx_t *c, int mdlen) +{ + int i; + + for (i = 0; i < 25; i++) + { + c->st.q[i] = 0; + } + c->mdlen = mdlen; + c->rsiz = 200 - 2 * mdlen; + c->pt = 0; + + return 1; +} + +/* update state with more data */ + +int tiny_sha3_update(sha3_ctx_t *c, const void *data, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) + { + c->st.b[j++] ^= ((const uint8_t *)data)[i]; + if (j >= c->rsiz) + { + tiny_sha3_keccakf(c->st.q); + j = 0; + } + } + c->pt = j; + + return 1; +} + +/* finalize and output a hash */ + +int tiny_sha3_final(void *md, sha3_ctx_t *c) +{ + int i; + + c->st.b[c->pt] ^= 0x06; + c->st.b[c->rsiz - 1] ^= 0x80; + tiny_sha3_keccakf(c->st.q); + + for (i = 0; i < c->mdlen; i++) + { + ((uint8_t *)md)[i] = c->st.b[i]; + } + + return 1; +} + +/* compute a SHA-3 hash (md) of given byte length from "in" */ + +void *tiny_sha3(const void *in, size_t inlen, void *md, int mdlen) +{ + sha3_ctx_t sha3; + + tiny_sha3_init(&sha3, mdlen); + tiny_sha3_update(&sha3, in, inlen); + tiny_sha3_final(md, &sha3); + + return md; +} + +/* SHAKE128 and SHAKE256 extensible-output functionality */ + +void tiny_shake_xof(sha3_ctx_t *c) +{ + c->st.b[c->pt] ^= 0x1F; + c->st.b[c->rsiz - 1] ^= 0x80; + tiny_sha3_keccakf(c->st.q); + c->pt = 0; +} + +void tiny_shake_out(sha3_ctx_t *c, void *out, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) + { + if (j >= c->rsiz) + { + tiny_sha3_keccakf(c->st.q); + j = 0; + } + ((uint8_t *)out)[i] = c->st.b[j++]; + } + c->pt = j; +} diff --git a/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/sha3.h b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/sha3.h new file mode 100644 index 000000000..a70c3d352 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/sha3.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: MIT + * + * sha3.h + * 19-Nov-11 Markku-Juhani O. Saarinen */ + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +/* state context */ +typedef struct +{ + union + { /* state: */ + uint8_t b[200]; /* 8-bit bytes */ + uint64_t q[25]; /* 64-bit words */ + } st; + int pt, rsiz, mdlen; /* these don't overflow */ +} sha3_ctx_t; + +/* Compression function. */ +void tiny_sha3_keccakf(uint64_t st[25]); + +/* OpenSSL - like interfece */ +int tiny_sha3_init(sha3_ctx_t *c, int mdlen); /* mdlen = hash output in bytes */ +int tiny_sha3_update(sha3_ctx_t *c, const void *data, size_t len); +int tiny_sha3_final(void *md, sha3_ctx_t *c); /* digest goes to md */ + +/* compute a sha3 hash (md) of given byte length from "in" */ +void *tiny_sha3(const void *in, size_t inlen, void *md, int mdlen); + +/* SHAKE128 and SHAKE256 extensible-output functions */ +#define tiny_shake128_init(c) tiny_sha3_init(c, 16) +#define tiny_shake256_init(c) tiny_sha3_init(c, 32) +#define tiny_shake_update tiny_sha3_update + +void tiny_shake_xof(sha3_ctx_t *c); +void tiny_shake_out(sha3_ctx_t *c, void *out, size_t len); + +#endif /* !SHA3_H */ diff --git a/examples/custom_backend/mldsa_native/mldsa/src/ntt.c b/examples/custom_backend/mldsa_native/mldsa/src/ntt.c new file mode 120000 index 000000000..591aae8f1 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/ntt.c @@ -0,0 +1 @@ +../../../../../mldsa/src/ntt.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/ntt.h b/examples/custom_backend/mldsa_native/mldsa/src/ntt.h new file mode 120000 index 000000000..130ce95e9 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/ntt.h @@ -0,0 +1 @@ +../../../../../mldsa/src/ntt.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/packing.c b/examples/custom_backend/mldsa_native/mldsa/src/packing.c new file mode 120000 index 000000000..f9858bbf7 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/packing.c @@ -0,0 +1 @@ +../../../../../mldsa/src/packing.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/packing.h b/examples/custom_backend/mldsa_native/mldsa/src/packing.h new file mode 120000 index 000000000..c2c549970 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/packing.h @@ -0,0 +1 @@ +../../../../../mldsa/src/packing.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/params.h b/examples/custom_backend/mldsa_native/mldsa/src/params.h new file mode 120000 index 000000000..f937b182b --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/params.h @@ -0,0 +1 @@ +../../../../../mldsa/src/params.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/poly.c b/examples/custom_backend/mldsa_native/mldsa/src/poly.c new file mode 120000 index 000000000..80d9cddfb --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/poly.c @@ -0,0 +1 @@ +../../../../../mldsa/src/poly.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/poly.h b/examples/custom_backend/mldsa_native/mldsa/src/poly.h new file mode 120000 index 000000000..d35a25290 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/poly.h @@ -0,0 +1 @@ +../../../../../mldsa/src/poly.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/poly_kl.c b/examples/custom_backend/mldsa_native/mldsa/src/poly_kl.c new file mode 120000 index 000000000..3e06c6042 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/poly_kl.c @@ -0,0 +1 @@ +../../../../../mldsa/src/poly_kl.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/poly_kl.h b/examples/custom_backend/mldsa_native/mldsa/src/poly_kl.h new file mode 120000 index 000000000..58915edbd --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/poly_kl.h @@ -0,0 +1 @@ +../../../../../mldsa/src/poly_kl.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/polyvec.c b/examples/custom_backend/mldsa_native/mldsa/src/polyvec.c new file mode 120000 index 000000000..811e00ff7 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/polyvec.c @@ -0,0 +1 @@ +../../../../../mldsa/src/polyvec.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/polyvec.h b/examples/custom_backend/mldsa_native/mldsa/src/polyvec.h new file mode 120000 index 000000000..21c07b544 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/polyvec.h @@ -0,0 +1 @@ +../../../../../mldsa/src/polyvec.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/randombytes.h b/examples/custom_backend/mldsa_native/mldsa/src/randombytes.h new file mode 120000 index 000000000..62f18cd46 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/randombytes.h @@ -0,0 +1 @@ +../../../../../mldsa/src/randombytes.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/reduce.h b/examples/custom_backend/mldsa_native/mldsa/src/reduce.h new file mode 120000 index 000000000..eff62136f --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/reduce.h @@ -0,0 +1 @@ +../../../../../mldsa/src/reduce.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/rounding.h b/examples/custom_backend/mldsa_native/mldsa/src/rounding.h new file mode 120000 index 000000000..245ec8a8b --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/rounding.h @@ -0,0 +1 @@ +../../../../../mldsa/src/rounding.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/sign.c b/examples/custom_backend/mldsa_native/mldsa/src/sign.c new file mode 120000 index 000000000..1363c3296 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/sign.c @@ -0,0 +1 @@ +../../../../../mldsa/src/sign.c \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/sign.h b/examples/custom_backend/mldsa_native/mldsa/src/sign.h new file mode 120000 index 000000000..1a2f09b39 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/sign.h @@ -0,0 +1 @@ +../../../../../mldsa/src/sign.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/symmetric.h b/examples/custom_backend/mldsa_native/mldsa/src/symmetric.h new file mode 120000 index 000000000..5ac08bdb5 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/symmetric.h @@ -0,0 +1 @@ +../../../../../mldsa/src/symmetric.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/sys.h b/examples/custom_backend/mldsa_native/mldsa/src/sys.h new file mode 120000 index 000000000..9aeae3de5 --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/sys.h @@ -0,0 +1 @@ +../../../../../mldsa/src/sys.h \ No newline at end of file diff --git a/examples/custom_backend/mldsa_native/mldsa/src/zetas.inc b/examples/custom_backend/mldsa_native/mldsa/src/zetas.inc new file mode 120000 index 000000000..d1703f74e --- /dev/null +++ b/examples/custom_backend/mldsa_native/mldsa/src/zetas.inc @@ -0,0 +1 @@ +../../../../../mldsa/src/zetas.inc \ No newline at end of file diff --git a/examples/custom_backend/test_only_rng/notrandombytes.c b/examples/custom_backend/test_only_rng/notrandombytes.c new file mode 120000 index 000000000..65b7801b8 --- /dev/null +++ b/examples/custom_backend/test_only_rng/notrandombytes.c @@ -0,0 +1 @@ +../../../test/notrandombytes/notrandombytes.c \ No newline at end of file diff --git a/examples/custom_backend/test_only_rng/notrandombytes.h b/examples/custom_backend/test_only_rng/notrandombytes.h new file mode 120000 index 000000000..e72c12b9c --- /dev/null +++ b/examples/custom_backend/test_only_rng/notrandombytes.h @@ -0,0 +1 @@ +../../../test/notrandombytes/notrandombytes.h \ No newline at end of file diff --git a/scripts/lint b/scripts/lint index 175fcfac5..4b749386f 100755 --- a/scripts/lint +++ b/scripts/lint @@ -157,7 +157,7 @@ check-spdx() success=false fi done - for file in $(git ls-files -- "*.[chsS]" "*.py" "*.mk" "*.yml" "**/Makefile*" ":/!proofs/cbmc/*.py" ":/!examples/bring_your_own_fips202/custom_fips202/tiny_sha3/*"); do + for file in $(git ls-files -- "*.[chsS]" "*.py" "*.mk" "*.yml" "**/Makefile*" ":/!proofs/cbmc/*.py" ":/!examples/bring_your_own_fips202/custom_fips202/tiny_sha3/*" ":/!examples/custom_backend/mldsa_native/mldsa/src/fips202/native/custom/src/*"); do # Ignore symlinks if [[ ! -L $file && $(grep "Copyright (c) The mldsa-native project authors" $file | wc -l) == 0 ]]; then gh_error "$file" "${line:-1}" "Missing copyright header error" "$file is missing copyright header" diff --git a/scripts/tests b/scripts/tests index 1be4894a7..221fa6b7b 100755 --- a/scripts/tests +++ b/scripts/tests @@ -208,6 +208,7 @@ class TEST_TYPES(Enum): BRING_YOUR_OWN_FIPS202_STATIC = 13 MONOLITHIC_BUILD_NATIVE = 14 MONOLITHIC_BUILD_MULTILEVEL_NATIVE = 15 + CUSTOM_BACKEND = 16 def is_benchmark(self): return self in [TEST_TYPES.BENCH, TEST_TYPES.BENCH_COMPONENTS] @@ -226,6 +227,7 @@ class TEST_TYPES(Enum): TEST_TYPES.BRING_YOUR_OWN_FIPS202_STATIC, TEST_TYPES.MONOLITHIC_BUILD_NATIVE, TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL_NATIVE, + TEST_TYPES.CUSTOM_BACKEND, ] @staticmethod @@ -271,6 +273,8 @@ class TEST_TYPES(Enum): return "Example (monobuild with native)" if self == TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL_NATIVE: return "Example (monobuild, multilevel with native)" + if self == TEST_TYPES.CUSTOM_BACKEND: + return "Example (Custom Backend)" def make_dir(self): if self == TEST_TYPES.BASIC: @@ -289,6 +293,8 @@ class TEST_TYPES(Enum): return "examples/monolithic_build_native" if self == TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL_NATIVE: return "examples/monolithic_build_multilevel_native" + if self == TEST_TYPES.CUSTOM_BACKEND: + return "examples/custom_backend" return "" def make_target(self): @@ -322,6 +328,8 @@ class TEST_TYPES(Enum): return "" if self == TEST_TYPES.MONOLITHIC_BUILD_MULTILEVEL_NATIVE: return "" + if self == TEST_TYPES.CUSTOM_BACKEND: + return "" def make_run_target(self, scheme): t = self.make_target() @@ -1100,7 +1108,7 @@ def cli(): choices=[ "bring_your_own_fips202", "bring_your_own_fips202_static", - # "custom_backend", + "custom_backend", "basic", "basic_deterministic", "monolithic_build", @@ -1156,6 +1164,7 @@ def cli(): "bring_your_own_fips202_static", "monolithic_build_native", "monolithic_build_multilevel_native", + "custom_backend", ], action="append", ) diff --git a/test/configs.yml b/test/configs.yml index 45b5660e9..fd0b7f7b6 100644 --- a/test/configs.yml +++ b/test/configs.yml @@ -379,6 +379,20 @@ configs: } #endif /* !__ASSEMBLER__ */ + - path: examples/custom_backend/mldsa_native/custom_config.h + description: "Custom backend config with tiny SHA3" + defines: + MLD_CONFIG_PARAMETER_SET: + comment: "/* This is set on the command line */" + MLD_CONFIG_USE_NATIVE_BACKEND_ARITH: + comment: "/* No native arithmetic backend */" + value: false + MLD_CONFIG_NAMESPACE_PREFIX: CUSTOM_TINY_SHA3 + MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202: true + MLD_CONFIG_FIPS202_BACKEND_FILE: '"fips202/native/custom/custom.h"' + MLD_CONFIG_FILE: + comment: "/* No need to set this -- we _are_ already in a custom config */" + - path: examples/basic_deterministic/mldsa_native/custom_no_randomized_config.h description: "Config without randomized API" defines: