244 lines
7.5 KiB
Markdown
244 lines
7.5 KiB
Markdown
# wolfSSL Post-Quantum Cryptography Stateful Hash-based Signatures Example
|
|
|
|
This directory contains:
|
|
|
|
- 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 to sign and verify a
|
|
message with a configurable XMSS/XMSS^MT parameter string. Requires wolfssl
|
|
with `--enable-xmss`.
|
|
|
|
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`.
|
|
|
|
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
|
|
|
|
This example will generate an LMS/HSS key pair with L=levels, H=height, and
|
|
W=Winternitz parameters, then sign and verify a given number of signatures.
|
|
It will also print the signature size, the total number of signatures, and
|
|
the public and private key lengths.
|
|
|
|
While LMS/HSS have small public and private keys, and fast signing and
|
|
verifying, the initial key generation can be quite slow and intensive,
|
|
especially for larger heights and Winternitz parameters.
|
|
|
|
LMS/HSS signature systems have a finite number of one-time signatures (OTS).
|
|
The number of available signatures is
|
|
N = 2 ** (levels * height)
|
|
|
|
The supported parameter values are those in RFC8554:
|
|
- levels = {1..8}
|
|
- height = {5, 10, 15, 20, 25}
|
|
- Winternitz = {1, 2, 4, 8}
|
|
|
|
To see the help and usage, run the program without options:
|
|
```sh
|
|
$./lms_example
|
|
usage:
|
|
./lms_example <levels> <height> <winternitz> [num signatures]
|
|
|
|
examples:
|
|
./lms_example 1 5 1
|
|
./lms_example 3 5 4 100
|
|
./lms_example 2 10 2 0
|
|
|
|
description:
|
|
...
|
|
```
|
|
## Signing and Verifying a Message with XMSS/XMSS^MT
|
|
|
|
To see the help and usage, run the program without options:
|
|
```sh
|
|
$ ./xmss_example
|
|
usage:
|
|
./xmss_example <param string> [num signatures]
|
|
|
|
examples:
|
|
./xmss_example XMSSMT-SHA2_20/4_256 5
|
|
./xmss_example XMSSMT-SHA2_60/6_256 100
|
|
./xmss_example XMSS-SHA2_10_256 1023
|
|
```
|
|
|
|
The param string may be any name from this table:
|
|
|
|
```
|
|
----------------------------------------------------------
|
|
| Name Oid n w len h d |
|
|
XMSS: | "XMSS-SHA2_10_256" 0x00000001 32 16 67 10 1 |
|
|
| "XMSS-SHA2_16_256" 0x00000002 32 16 67 16 1 |
|
|
| "XMSS-SHA2_20_256" 0x00000003 32 16 67 20 1 |
|
|
| |
|
|
XMSSMT: | "XMSSMT-SHA2_20/2_256" 0x00000001 32 16 67 20 2 |
|
|
| "XMSSMT-SHA2_20/4_256" 0x00000002 32 16 67 20 4 |
|
|
| "XMSSMT-SHA2_40/2_256" 0x00000003 32 16 67 40 2 |
|
|
| "XMSSMT-SHA2_40/4_256" 0x00000004 32 16 67 40 4 |
|
|
| "XMSSMT-SHA2_40/8_256" 0x00000005 32 16 67 40 8 |
|
|
| "XMSSMT-SHA2_60/3_256" 0x00000006 32 16 67 60 3 |
|
|
| "XMSSMT-SHA2_60/6_256" 0x00000007 32 16 67 60 6 |
|
|
| "XMSSMT-SHA2_60/12_256" 0x00000008 32 16 67 60 12 |
|
|
----------------------------------------------------------
|
|
```
|
|
|
|
Here `n=32` is the number of bytes in the SHA256 has function, `w=16`
|
|
is the Winternitz parameter, `len=67` is the length of Winternitz chains,
|
|
`h` is the is the total height of the tree or hyper-tree, and `d` is the
|
|
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.
|
|
|
|
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 default
|
|
implementation has larger private key sizes for greater signing
|
|
performance.
|
|
|
|
For example this is obtained with the default `-enable-xmss` with
|
|
`--enable-intelasm` (on an Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz):
|
|
|
|
```
|
|
$time ./xmss_example "XMSSMT-SHA2_20/2_256" 200
|
|
using parameters: XMSSMT-SHA2_20/2_256
|
|
signature length: 4963
|
|
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:
|
|
|
|
```
|
|
$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 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
|
|
usage:
|
|
./xmss_example <param string> <pub file> <sig file> <msg file>
|
|
|
|
For simplicity message is assumed to be 32 bytes in size.
|
|
|
|
examples:
|
|
./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 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
|
|
0x32 0x4B 0x15 0xA8 0xF6 0xEA 0x04 0xC0
|
|
0x96 0x52 0x70 0x4D 0x4C 0x19 0x94 0xA4
|
|
0x2D 0x2E 0xDA 0x52 0xA4 0x5F 0xF7 0xA8
|
|
0x50 0x0A 0xE1 0xB3 0x77 0xD6 0x85 0x33
|
|
0xB0 0x8A 0x4F 0x9D 0x54 0x6B 0xE9 0xFE
|
|
0x4B 0x3B 0xCB 0x5A 0x7A 0x92 0x86 0x0C
|
|
0x4B 0x7F 0xBF 0x2E 0xA0 0x1F 0x47 0x6F
|
|
0xDB 0x35 0x1C 0x61
|
|
msg:
|
|
0xF1 0x91 0x9C 0xC0 0xA7 0xDC 0xEB 0xCE
|
|
0x38 0x96 0xEC 0x28 0x3A 0x9E 0xE1 0xA0
|
|
0xA3 0x2F 0x94 0x1E 0xE7 0xB0 0x56 0x15
|
|
0x54 0x8C 0x17 0xF4 0x65 0xFF 0xCB 0x08
|
|
signature length: 4963
|
|
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
|
|
```
|