Skip to content

Commit

Permalink
Add example for custom config and custom FIPS-202 backend
Browse files Browse the repository at this point in the history
This commit adds another minimal example to `examples/`, demonstrating
how to use a custom configuration file and a custom FIPS-202 backend.

Signed-off-by: Hanno Becker <[email protected]>
  • Loading branch information
hanno-becker committed Dec 16, 2024
1 parent 665f02e commit 85c1cdf
Show file tree
Hide file tree
Showing 53 changed files with 818 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ jobs:
- name: bring_your_own_fips202
run: |
make run -C examples/bring_your_own_fips202
- name: custom_backend
run: |
make run -C examples/custom_backend
build_kat:
needs: [quickcheck, quickcheck-windows]
strategy:
Expand Down
5 changes: 5 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ See [mlkem_native_as_code_package](mlkem_native_as_code_package).

See [bring_your_own_fips202](bring_your_own_fips202) for an example of how to use mlkem-native with your own FIPS-202
implementation.

## Using mlkem-native as a code package, custom config + custom FIPS-202 backend

See [custom_backend](custom_backend) for an example of how to use mlkem-native with a custom configuration file and a
custom FIPS-202 backend.
64 changes: 64 additions & 0 deletions examples/custom_backend/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# (SPDX-License-Identifier: CC-BY-4.0)

.PHONY: build run clean

# Part A:
#
# mlkem-native source and header files
#
# If you are not concerned about minimizing for a specific backend,
# you can just include _all_ source files into your build.
MLKEM_NATIVE_SOURCE=$(wildcard \
mlkem_native/**/*.c \
mlkem_native/**/*.c \
mlkem_native/**/**/*.c \
mlkem_native/**/**/**/*.c \
mlkem_native/**/**/**/**/*.c)

INC=
INC+=-Imlkem_native/
INC+=-Imlkem_native/mlkem
INC+=-Imlkem_native/mlkem/native
INC+=-Imlkem_native/fips202
INC+=-Imlkem_native/fips202/native

# 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=$(MLKEM_NATIVE_SOURCE) $(RNG_SOURCE) $(APP_SOURCE)

BUILD_DIR=build
BIN=test_binary

CFLAGS=-DMLKEM_NATIVE_CONFIG_FILE="\"custom_config.h\""

BINARY_NAME_FULL=$(BUILD_DIR)/$(BIN)

$(BINARY_NAME_FULL): $(ALL_SOURCE)
echo "$@"
mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) $(INC) $^ -o $@

all: run

build: $(BINARY_NAME_FULL)

run: $(BINARY_NAME_FULL)
./$(BINARY_NAME_FULL)

clean:
rm -rf $(BUILD_DIR)
34 changes: 34 additions & 0 deletions examples/custom_backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[//]: # (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 mlkem-native as a code package, with a custom FIPS-202
backend and a custom configuration. We use the [tiny_sha3](https://github.com/mjosaarinen/tiny_sha3/) by Markku-J. O.
Saarinen as an example.

## Components

An application using mlkem-native with a custom FIPS-202 backend and custom configuration needs the following:

1. Arithmetic part of the mlkem-native source tree: [`mlkem/`](../../mlkem). 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`](../../mlkem/randombytes.h).
3. FIPS-202 part of the mlkem-native source tree, [`fips/`](../../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 metadata file is
[custom.h](mlkem_native/fips202/native/custom/custom.h), the implementation shim is
[custom_impl.h](mlkem_native/fips202/native/custom/src/custom_impl.h), wrapping the
[sha3.c](mlkem_native/fips202/native/custom/src/sha3.c) and setting `MLKEM_USE_FIPS101_X1_NATIVE` to indicate that we
replace 1-fold Keccak-F1600.
5. Either modify the existing [config.h](mlkem_native/mlkem/config.h), or register a new config. In this example, we add
a new config [custom_config.h](mlkem_native/custom_config.h) and register it from the command line for
`-DMLKEM_NATIVE_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 `MLKEM_NATIVE_FIPS202_BACKEND` to point to our custom FIPS-202
backend, but leave `MLKEM_NATIVE_ARITH_BACKEND` undefined to indicate that we wish to use the C backend.

**WARNING:** The `randombytes()` implementation used here is for TESTING ONLY. You MUST NOT use this implementation
outside of testing.

## Usage

Build this example with `make build`, run with `make run`.
56 changes: 56 additions & 0 deletions examples/custom_backend/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdio.h>
#include <string.h>

#include <kem.h>

int main(void)
{
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
uint8_t sk[CRYPTO_SECRETKEYBYTES];
uint8_t ct[CRYPTO_CIPHERTEXTBYTES];
uint8_t key_a[CRYPTO_BYTES];
uint8_t key_b[CRYPTO_BYTES];

printf("Generating keypair ... ");

/* Alice generates a public key */
crypto_kem_keypair(pk, sk);

printf("DONE\n");
printf("Encaps... ");

/* Bob derives a secret key and creates a response */
crypto_kem_enc(ct, key_b, pk);

printf("DONE\n");
printf("Decaps... ");

/* Alice uses Bobs response to get her shared key */
crypto_kem_dec(key_a, ct, sk);

printf("DONE\n");
printf("Compare... ");

if (memcmp(key_a, key_b, CRYPTO_BYTES))
{
printf("ERROR\n");
return 1;
}

printf("OK\n");

printf("Shared secret: ");
{
int i;
for (i = 0; i < sizeof(key_a); i++)
printf("%02x", key_a[i]);
}
printf("\n");

return 0;
}
113 changes: 113 additions & 0 deletions examples/custom_backend/mlkem_native/custom_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2024 The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef MLKEM_NATIVE_CONFIG_H
#define MLKEM_NATIVE_CONFIG_H

/******************************************************************************
* Name: MLKEM_K
*
* Description: Determines the security level for ML-KEM
* - MLKEM_K=2 corresponds to ML-KEM-512
* - MLKEM_K=3 corresponds to ML-KEM-768
* - MLKEM_K=4 corresponds to ML-KEM-1024
*
* This can also be set using CFLAGS.
*
*****************************************************************************/
#define MLKEM_K 4 /* We want MLKEM-1024 */

/******************************************************************************
* Name: MLKEM_NATIVE_CONFIG_FILE
*
* Description: If defined, this is a header that will be included instead
* of mlkem/config.h.
*
* When you need to build mlkem-native in multiple configurations,
* this can be a convenient alternative to configuration via
* CFLAGS.
*
*****************************************************************************/
/* No need to set this -- we _are_ already in a custom config */
/* #define MLKEM_NATIVE_CONFIG_FILE "config.h" */

/******************************************************************************
* Name: MLKEM_NAMESPACE
* _MLKEM_NAMESPACE
*
* Description: The macros to use to namespace global symbols
* from mlkem/.
*****************************************************************************/
#define __CONC(a, b) a##b
#define CONC(a, b) __CONC(a, b)

#define MLKEM_NAMESPACE(sym) CONC(CUSTOM_TINY_SHA3_, sym)
#define _MLKEM_NAMESPACE(sym) CONC(_CUSTOM_TINY_SHA3_, sym)

/******************************************************************************
* Name: FIPS202_NAMESPACE
* _FIPS202_NAMESPACE
*
* Description: The macros to use to namespace global symbols
* from fips202/.
*****************************************************************************/
#define FIPS202_NAMESPACE(sym) CONC(CUSTOM_TINY_SHA3_, sym)
#define _FIPS202_NAMESPACE(sym) CONC(_CUSTOM_TINY_SHA3_, sym)

/******************************************************************************
* Name: MLKEM_USE_NATIVE
*
* Description: Determines whether a native backend should
* be used, if available.
*
* This can also be set using CFLAGS.
*
*****************************************************************************/
#define MLKEM_USE_NATIVE

/******************************************************************************
* Name: MLKEM_NATIVE_ARITH_BACKEND
*
* Description: The arithmetic backend to use.
*
* This must be the filename of an arithmetic
* backend. The backend is expected to define
*
* - MLKEM_NATIVE_ARITH_BACKEND_NAME
*
* The name of the backend as used in the default namespace.
*
* - MLKEM_NATIVE_ARITH_BACKEND_IMPL
*
* The filename of the implementation of the arithmetic backend.
*
* See the existing backends for more information.
*
*****************************************************************************/
/* Let's pretend we don't want an arithmetic backend */
/* #define MLKEM_NATIVE_ARITH_BACKEND "native/default.h" */

/******************************************************************************
* Name: MLKEM_NATIVE_FIPS202_BACKEND
*
* Description: The FIPS-202 backend to use.
*
* This must be the filename of an FIPS-202
* backend. The backend is expected to define
*
* - MLKEM_NATIVE_FIPS202_BACKEND_NAME
*
* The name of the backend as used in the default namespace.
*
* - MLKEM_NATIVE_FIPS202_BACKEND_IMPL
*
* The filename of the implementation of the FIPS-202 backend.
*
* See the existing backends for more information.
*
*****************************************************************************/
#define MLKEM_NATIVE_FIPS202_BACKEND "fips202/native/custom/custom.h"

#endif /* MLkEM_NATIVE_CONFIG_H */
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/LICENSE
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/fips202.c
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/fips202.h
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/fips202x4.c
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/fips202x4.h
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/keccakf1600.c
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/keccakf1600.h
1 change: 1 addition & 0 deletions examples/custom_backend/mlkem_native/fips202/native/api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2024 The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0
*/

/* Default FIPS202 assembly profile for AArch64 systems */

#ifdef FIPS202_NATIVE_PROFILE_H
#error Only one FIPS202 assembly profile can be defined -- did you include multiple profiles?
#else
#define FIPS202_NATIVE_PROFILE_H

/* Identifier for this backend so that source and assembly files
* in the build can be appropriately guarded. */
#define MLKEM_NATIVE_FIPS202_BACKEND_CUSTOM_TINY_SHA3

#define MLKEM_NATIVE_FIPS202_BACKEND_NAME TINY_SHA3

/* Filename of the C backend implementation.
* This is not inlined here because this header is included in assembly
* files as well. */
#define MLKEM_NATIVE_FIPS202_BACKEND_IMPL \
"fips202/native/custom/src/custom_impl.h"

#endif /* FIPS202_NATIVE_PROFILE_H */
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-License-Identifier: MIT

# Makefile
# 19-Nov-11 Markku-Juhani O. Saarinen <[email protected]>

BINARY = sha3test
OBJS = sha3.o main.o
DIST = tiny_sha3

CC = gcc
CFLAGS = -Wall -O3
LIBS =
LDFLAGS =
INCLUDES =

$(BINARY): $(OBJS)
$(CC) $(LDFLAGS) -o $(BINARY) $(OBJS) $(LIBS)

.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

clean:
rm -rf $(DIST)-*.txz $(OBJS) $(BINARY) *~

dist: clean
cd ..; \
tar cfvJ $(DIST)/$(DIST)-`date -u "+%Y%m%d%H%M00"`.txz \
$(DIST)/*
Loading

0 comments on commit 85c1cdf

Please sign in to comment.