Skip to content

Commit

Permalink
Merge pull request #436 from philljj/update_lms_xmss_examples
Browse files Browse the repository at this point in the history
Update lms xmss examples
  • Loading branch information
dgarske committed May 13, 2024
2 parents 2326995 + 1252dd6 commit a68fe84
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 114 deletions.
36 changes: 19 additions & 17 deletions pq/stateful_hash_sig/Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
# PQ Stateful Hash-Based Signature Examples Makefile
#
# XMSS_INC, XMSS_LIB, and WOLF_STATIC_LIB are only required if
# building with --with-libxmss.
# HSS_INC, HSS_LIB, XMSS_INC, XMSS_LIB, and WOLF_STATIC_LIB are only
# required if building with --with-libxmss or --with-liblms.
#
CC = gcc
WOLFSSL_INSTALL_DIR = /usr/local
HSS_INC =
XMSS_INC =
CFLAGS = -Wall -I$(WOLFSSL_INSTALL_DIR)/include
LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lm

# option variables
WOLF_DYN_LIB = -lwolfssl
WOLF_STATIC_LIB = $(WOLFSSL_INSTALL_DIR)/lib/libwolfssl.a
HSS_LIB =
XMSS_LIB =

# These are only needed if building with the external
# integration (ext_lms, ext_xmss).
# HSS_INC = path to hash-sigs src dir
# XMSS_INC = path to xmss-reference src dir
# HSS_LIB = path to hash-sigs hss_lib.a
# XMSS_LIB = path to xmss-reference xmss_lib.a

# Options
DEBUG_FLAGS = -g -DDEBUG
DEBUG_INC_PATHS = -MD
OPTIMIZE = -Os

# Options
#CFLAGS+=$(DEBUG_FLAGS)
#CFLAGS+=$(OPTIMIZE)

Expand All @@ -36,19 +39,18 @@ debug: all

# build template
lms_example: lms_example.c
$(CC) -o $@ $< $(CFLAGS) -I$(HSS_INC) $(LIBS) $(WOLF_STATIC_LIB) $(HSS_LIB)
# If building with wc_lms (--enable-lms):
$(CC) -o $@ $< $(CFLAGS) -DWOLFSSL_WC_LMS $(LIBS) $(WOLF_DYN_LIB)
# If building with ext_lms (--enable-lms --with-liblms=<path>):
# $(CC) -o $@ $< $(CFLAGS) -I$(HSS_INC) $(LIBS) $(WOLF_STATIC_LIB) $(HSS_LIB)

xmss_example: xmss_example.c
# If building with --enable-xmss=wolfssl:
$(CC) -o $@ $< $(CFLAGS) -I$(XMSS_INC) $(LIBS) $(WOLF_STATIC_LIB) $(XMSS_LIB)
# If building with --enable-xmss --with-libxmss=<path>:
# $(CC) -o $@ $< $(CFLAGS) $(LIBS) $(WOLF_DYN_LIB)

xmss_example_verifyonly: xmss_example.c
$(CC) -o $@ $< $(CFLAGS) -I$(XMSS_INC) -DWOLFSSL_XMSS_VERIFY_ONLY $(LIBS) $(WOLF_STATIC_LIB) $(XMSS_LIB)
# If building with wc_xmss (--enable-xmss):
$(CC) -o $@ $< $(CFLAGS) -DWOLFSSL_WC_XMSS $(LIBS) $(WOLF_DYN_LIB)
# If building with ext_xmss (--enable-xmss --with-libxmss=<path>):
# $(CC) -o $@ $< $(CFLAGS) -I$(XMSS_INC) $(LIBS) $(WOLF_STATIC_LIB) $(XMSS_LIB)

clean:
rm -f $(TARGETS)
rm -f xmss_example_verifyonly
rm -f lms_example.key
rm -f xmss_example.key
186 changes: 102 additions & 84 deletions pq/stateful_hash_sig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,21 @@

This directory contains:

- A simple example that uses wolfCrypt LMS/HSS hooks to sign and verify a message
with configurable LMS/HSS parameters. Requires wolfssl with `--enable-lms=yes`
and `--with-liblms=<path to hash-sigs install>`.
- An example that uses wolfCrypt LMS/HSS to sign and verify a
message with configurable LMS/HSS parameters. Requires wolfssl with
`--enable-lms`.

- An example that uses wolfCrypt XMSS/XMSS^MT hooks to sign and verify a message
with a configurable XMSS/XMSS^MT parameter string. Requires wolfssl with `--enable-xmss=yes`
and `--with-libxmss=<path to patched xmss-reference install>`, or wolfssl
with `--enable-xmss=wolfssl`.
- An example that uses wolfCrypt XMSS/XMSS^MT to sign and verify a
message with a configurable XMSS/XMSS^MT parameter string. Requires wolfssl
with `--enable-xmss`.

# Prerequisites
By default these examples use the wolfCrypt LMS and XMSS implementations
(`wc_lms.c`, `wc_lms_impl.c`, `wc_xmss.c`, `wc_xmss_impl.c`), which are more
performant and configurable. Also, these implementations benefit significantly
from `--enable-intelasm` and `--enable-armasm`.

The LMS/HSS sign verify example requires that hash-sigs has been built, and
wolfSSL has been built with LMS/HSS support enabled. Please see Item 17
in the wolfSSL repo's INSTALL file.

https://github.com/wolfSSL/wolfssl/blob/master/INSTALL

If building with `--with-libxmss=<path>`, the XMSS/XMSS^MT example requires
that the xmss-reference repository has been cloned, patched, and built. Please
see item 20 in the wolfSSL repo's INSTALL file.

The patch to use is `0001-Patch-to-support-wolfSSL-xmss-reference-integration.patch` from this XMSS/XMSS^MT example.
This patch includes an addendum readme, `patch_readme.md`, that lists all changes made and explains their rationale.

# Building the LMS/HSS example

Configure the Makefile to point to your hash-sigs install:

```
HSS_INC = <path to hss install>
```

```
HSS_LIB = <path to hss_lib_thread.a>
```

Then build:

```
$ make lms_example
```
If you want to use the old external integrations (`ext_lms.c`, `ext_xmss.c`),
see the section "Building the External Integration examples".

## Signing and Verifying a Message with LMS/HSS

Expand Down Expand Up @@ -78,31 +52,6 @@ examples:
description:
...
```

# Building the XMSS/XMSS^MT example

If building with `--with-libxmss=<path>`, configure the Makefile to point to
your xmss install:

```
XMSS_INC = <path to patched xmss install>
```

```
XMSS_LIB = <path to xmss_lib.a or xmss_verify_lib.a>
```

Then build:

```
$ make xmss_example
```

Build the verify-only example with
```
$ make xmss_example_verifyonly
```

## Signing and Verifying a Message with XMSS/XMSS^MT

To see the help and usage, run the program without options:
Expand Down Expand Up @@ -144,64 +93,76 @@ number of levels in the hyper-tree. The number of signatures available
is `N = 2 ** (h)`.

The main contributor to key generation time is the ratio `h/d`.
Not surprisingly, be aware that `XMSS-SHA2_20_256`, and `XMSSMT-SHA2_60/3_256`, are particularly
CPU intensive because of the large number of hash operations involved, and
may take a long time. E.g. on an Intel i7 linux system these examples took
approximately 24 min, and 1 hour, respectively.
Not surprisingly, be aware that `XMSS-SHA2_20_256`, and `XMSSMT-SHA2_60/3_256`,
are particularly CPU intensive because of the large number of hash operations
involved, and may take a long time.

The other examples will be much faster.

An interesting facet of XMSS/XMSS^MT is that the private key format
and size is implementation specific. The wolfSSL XMSS/XMSS^MT hooks
feature uses the "fast" implementation from xmss-reference, which
has larger private key sizes.
and size is implementation specific. The wolfSSL XMSS/XMSS^MT default
implementation has larger private key sizes for greater signing
performance.

For example:
For example this is obtained with the default `-enable-xmss` with
`--enable-intelasm` (on an Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz):

```
$ ./xmss_example "XMSSMT-SHA2_20/2_256" 200
$time ./xmss_example "XMSSMT-SHA2_20/2_256" 200
using parameters: XMSSMT-SHA2_20/2_256
signature length: 4963
priv key length: 6002
priv key length: 5780
pub key length: 68
making key with XMSSMT-SHA2_20/2_256 parameters...
...done!
signing and verifying 200 signatures...
...done!
finished
real 0m2.115s
user 0m2.104s
sys 0m0.007s
```

Versus the same with `--enable-xmss=small` instead:

```
$ ./xmss_example "XMSSMT-SHA2_40/4_256" 200
using parameters: XMSSMT-SHA2_40/4_256
signature length: 9893
priv key length: 15256
$time ./xmss_example "XMSSMT-SHA2_20/2_256" 200
using parameters: XMSSMT-SHA2_20/2_256
signature length: 4963
priv key length: 135
pub key length: 68
making key with XMSSMT-SHA2_20/2_256 parameters...
...done!
signing and verifying 200 signatures...
...done!
finished
real 6m57.413s
user 6m56.337s
sys 0m0.058s
```

## Using the verify-only XMSS/XMSS^MT example

The usage for the verify-only example is:
The verify-only XMSS example requires that wolfSSL has been built with
`--enable-xmss=verify-only`. The usage for the verify-only example is:
```
$ ./xmss_example_verifyonly
$ ./xmss_example
usage:
./xmss_example_verifyonly <param string> <pub file> <sig file> <msg file>
./xmss_example <param string> <pub file> <sig file> <msg file>
For simplicity message is assumed to be 32 bytes in size.
examples:
./xmss_example_verifyonly XMSSMT-SHA2_20/4_256 xmss_pub.key xmss_sig.bin msg.bin
./xmss_example_verifyonly XMSSMT-SHA2_60/6_256 xmss_pub.key xmss_sig.bin msg.bin
./xmss_example_verifyonly XMSS-SHA2_10_256 xmss_pub.key xmss_sig.bin msg.bin
./xmss_example XMSSMT-SHA2_20/4_256 xmss_pub.key xmss_sig.bin msg.bin
./xmss_example XMSSMT-SHA2_60/6_256 xmss_pub.key xmss_sig.bin msg.bin
./xmss_example XMSS-SHA2_10_256 xmss_pub.key xmss_sig.bin msg.bin
```

An example:
```
$./xmss_example_verifyonly XMSSMT-SHA2_20/2_256 pk.bin sig.bin msg.bin
$./xmss_example XMSSMT-SHA2_20/2_256 pk.bin sig.bin msg.bin
using parameters: XMSSMT-SHA2_20/2_256
pub:
0x00 0x00 0x00 0x01 0x2B 0xC1 0xA4 0x8D
Expand All @@ -223,3 +184,60 @@ pub key length: 68
Verify good!
finished
```


# Building the External Integration examples

By default wolfssl uses the wolfCrypt LMS/XMSS implementations. However
the previous external integrations are still supported.

If building with `--with-liblms=<path>`, the LMS/HSS example requires
that hash-sigs has been built. Please see Item 17 in the wolfSSL repo's INSTALL file.

https://github.com/wolfSSL/wolfssl/blob/master/INSTALL

If building with `--with-libxmss=<path>`, the XMSS/XMSS^MT example requires
that the xmss-reference repository has been cloned, patched, and built. Please
see item 20 in the wolfSSL repo's INSTALL file.

The patch to use is `0001-Patch-to-support-wolfSSL-xmss-reference-integration.patch`
from this XMSS/XMSS^MT example. This patch includes an addendum readme,
`patch_readme.md`, that lists all changes made and explains their rationale.

## Building the external LMS/HSS example

If building with `--with-liblms=<path>`, configure the Makefile to point
to your hash-sigs install:

```
HSS_INC = <path to hss install>
```

```
HSS_LIB = <path to hss_lib_thread.a>
```

Then build:

```
$ make lms_example
```

## Building the external XMSS/XMSS^MT example

If building with `--with-libxmss=<path>`, configure the Makefile to point to
your xmss install:

```
XMSS_INC = <path to patched xmss install>
```

```
XMSS_LIB = <path to xmss_lib.a or xmss_verify_lib.a>
```

Then build:

```
$ make xmss_example
```
24 changes: 17 additions & 7 deletions pq/stateful_hash_sig/lms_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,21 @@
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/error-crypt.h>

#ifdef HAVE_LIBLMS
#ifdef WOLFSSL_HAVE_LMS

#include <wolfssl/wolfcrypt/lms.h>
#include <wolfssl/wolfcrypt/ext_lms.h>
#ifdef HAVE_LIBLMS
#include <wolfssl/wolfcrypt/ext_lms.h>
#else
#include <wolfssl/wolfcrypt/wc_lms.h>
#endif

static void print_usage(void);
static int write_key_file(const byte * priv, word32 privSz, void * context);
static int read_key_file(byte * priv, word32 privSz, void * context);
static int do_lms_example(int levels, int height, int winternitz,
size_t sigs_to_do);
static void dump_hex(const char * what, const uint8_t * buf, size_t len);
static void dump_hex(const char * what, const byte * buf, size_t len);

static WC_RNG rng;

Expand Down Expand Up @@ -248,6 +252,12 @@ do_lms_example(int levels,
goto exit_lms_example;
}

ret = wc_LmsKey_Init(&verifyKey, NULL, 0);
if (ret) {
fprintf(stderr, "error: wc_LmsKey_Init returned %d\n", ret);
goto exit_lms_example;
}

ret = wc_LmsKey_SetParameters(&signingKey, levels, height, winternitz);
if (ret) {
fprintf(stderr, "error: wc_LmsKey_SetParameters(%d, %d, %d) returned %d\n",
Expand Down Expand Up @@ -374,9 +384,9 @@ do_lms_example(int levels,
}

static void
dump_hex(const char * what,
const uint8_t * buf,
size_t len)
dump_hex(const char * what,
const byte * buf,
size_t len)
{
printf("%s\n", what);
for (size_t i = 0; i < len; ++i) {
Expand All @@ -400,5 +410,5 @@ int main(int argc, char** argv) {
printf("This requires the --with-liblms flag.\n");
return 0;
}
#endif /* WITH_LILMS */
#endif /* WOLFSSL_HAVE_LMS */

0 comments on commit a68fe84

Please sign in to comment.