From 946e6f3e7e5bd6ea0243283009dbd61ff166bee6 Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 9 May 2024 15:08:29 -0500 Subject: [PATCH 1/3] Update LMS and XMSS examples. --- pq/stateful_hash_sig/Makefile | 36 +++--- pq/stateful_hash_sig/README.md | 187 +++++++++++++++------------- pq/stateful_hash_sig/lms_example.c | 18 +-- pq/stateful_hash_sig/xmss_example.c | 12 +- 4 files changed, 139 insertions(+), 114 deletions(-) diff --git a/pq/stateful_hash_sig/Makefile b/pq/stateful_hash_sig/Makefile index 77e41758..e6271277 100644 --- a/pq/stateful_hash_sig/Makefile +++ b/pq/stateful_hash_sig/Makefile @@ -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) @@ -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=): +# $(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=: -# $(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=): +# $(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 diff --git a/pq/stateful_hash_sig/README.md b/pq/stateful_hash_sig/README.md index 17ce5750..69b89df2 100644 --- a/pq/stateful_hash_sig/README.md +++ b/pq/stateful_hash_sig/README.md @@ -2,47 +2,22 @@ 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=`. +- 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=`, 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=`, 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 = -``` - -``` -HSS_LIB = -``` - -Then build: - -``` -$ make lms_example -``` +If you want to use the old external integrations LMS/XMSS implementations +(`ext_lms.c`, `ext_xmss.c`), see the section "Building the External Integration +examples". ## Signing and Verifying a Message with LMS/HSS @@ -78,31 +53,6 @@ examples: description: ... ``` - -# Building the XMSS/XMSS^MT example - -If building with `--with-libxmss=`, configure the Makefile to point to -your xmss install: - -``` -XMSS_INC = -``` - -``` -XMSS_LIB = -``` - -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: @@ -144,64 +94,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 + ./xmss_example 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 @@ -223,3 +185,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=`, 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=`, 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=`, configure the Makefile to point +to your hash-sigs install: + +``` +HSS_INC = +``` + +``` +HSS_LIB = +``` + +Then build: + +``` +$ make lms_example +``` + +# Building the external XMSS/XMSS^MT example + +If building with `--with-libxmss=`, configure the Makefile to point to +your xmss install: + +``` +XMSS_INC = +``` + +``` +XMSS_LIB = +``` + +Then build: + +``` +$ make xmss_example +``` diff --git a/pq/stateful_hash_sig/lms_example.c b/pq/stateful_hash_sig/lms_example.c index 1094ba5e..e8fab346 100644 --- a/pq/stateful_hash_sig/lms_example.c +++ b/pq/stateful_hash_sig/lms_example.c @@ -24,17 +24,21 @@ #include #include -#ifdef HAVE_LIBLMS +#ifdef WOLFSSL_HAVE_LMS #include -#include +#ifdef HAVE_LIBLMS + #include +#else + #include +#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; @@ -374,9 +378,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) { @@ -400,5 +404,5 @@ int main(int argc, char** argv) { printf("This requires the --with-liblms flag.\n"); return 0; } -#endif /* WITH_LILMS */ +#endif /* WOLFSSL_HAVE_LMS */ diff --git a/pq/stateful_hash_sig/xmss_example.c b/pq/stateful_hash_sig/xmss_example.c index 223d0f92..11acd364 100644 --- a/pq/stateful_hash_sig/xmss_example.c +++ b/pq/stateful_hash_sig/xmss_example.c @@ -38,7 +38,7 @@ static void print_usage(void); #if !defined WOLFSSL_XMSS_VERIFY_ONLY static int do_xmss_example(const char * params, size_t sigs_to_do); static enum wc_XmssRc write_key_file(const byte * priv, word32 privSz, - void * context); + void * context); static enum wc_XmssRc read_key_file(byte * priv, word32 privSz, void * context); @@ -385,14 +385,14 @@ static void print_usage(void) { fprintf(stderr, "usage:\n"); - fprintf(stderr, " ./xmss_example_verifyonly \n"); + fprintf(stderr, " ./xmss_example \n"); fprintf(stderr, "\n"); fprintf(stderr, "For simplicity message is assumed to be 32 bytes in size.\n"); fprintf(stderr, "\n"); fprintf(stderr, "examples:\n"); - fprintf(stderr, " ./xmss_example_verifyonly XMSSMT-SHA2_20/4_256 xmss_pub.key xmss_sig.bin msg.bin\n"); - fprintf(stderr, " ./xmss_example_verifyonly XMSSMT-SHA2_60/6_256 xmss_pub.key xmss_sig.bin msg.bin\n"); - fprintf(stderr, " ./xmss_example_verifyonly XMSS-SHA2_10_256 xmss_pub.key xmss_sig.bin msg.bin\n"); + fprintf(stderr, " ./xmss_example XMSSMT-SHA2_20/4_256 xmss_pub.key xmss_sig.bin msg.bin\n"); + fprintf(stderr, " ./xmss_example XMSSMT-SHA2_60/6_256 xmss_pub.key xmss_sig.bin msg.bin\n"); + fprintf(stderr, " ./xmss_example XMSS-SHA2_10_256 xmss_pub.key xmss_sig.bin msg.bin\n"); exit(EXIT_FAILURE); } @@ -561,5 +561,5 @@ int main(int argc, char** argv) { printf("This requires --enable-xmss.\n"); return 0; } -#endif /* WITH_LIBXMSS */ +#endif /* WOLFSSL_HAVE_XMSS */ From 64aedb43d0d2db82b7ddb92d9d4ab539ddab5f2f Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 9 May 2024 15:12:26 -0500 Subject: [PATCH 2/3] Small readme cleanup. --- pq/stateful_hash_sig/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pq/stateful_hash_sig/README.md b/pq/stateful_hash_sig/README.md index 69b89df2..a5612c1e 100644 --- a/pq/stateful_hash_sig/README.md +++ b/pq/stateful_hash_sig/README.md @@ -15,9 +15,8 @@ By default these examples use the wolfCrypt LMS and XMSS implementations performant and configurable. Also, these implementations benefit significantly from `--enable-intelasm` and `--enable-armasm`. -If you want to use the old external integrations LMS/XMSS implementations -(`ext_lms.c`, `ext_xmss.c`), see the section "Building the External Integration -examples". +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 @@ -224,7 +223,7 @@ Then build: $ make lms_example ``` -# Building the external XMSS/XMSS^MT example +## Building the external XMSS/XMSS^MT example If building with `--with-libxmss=`, configure the Makefile to point to your xmss install: From 1252dd6a34cd0833a897594913a53b952ce90e0c Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 9 May 2024 15:31:11 -0500 Subject: [PATCH 3/3] Add missing wc_LmsKey_Init call. --- pq/stateful_hash_sig/lms_example.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pq/stateful_hash_sig/lms_example.c b/pq/stateful_hash_sig/lms_example.c index e8fab346..33a40cbc 100644 --- a/pq/stateful_hash_sig/lms_example.c +++ b/pq/stateful_hash_sig/lms_example.c @@ -252,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",