mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 03:10:50 +02:00
Merge pull request #7500 from SparkiDev/lms_xmss_move_wolfcrypt
LMS, XMSS: move code into wolfCrypt
This commit is contained in:
+26
-42
@@ -1229,7 +1229,6 @@ AC_ARG_ENABLE([xmss],
|
||||
[ ENABLED_XMSS=no ]
|
||||
)
|
||||
|
||||
ENABLED_WC_XMSS=no
|
||||
for v in `echo $ENABLED_XMSS | tr "," " "`
|
||||
do
|
||||
case $v in
|
||||
@@ -1238,15 +1237,9 @@ do
|
||||
no)
|
||||
;;
|
||||
verify-only)
|
||||
XMSS_VERIFY_ONLY=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_XMSS_VERIFY_ONLY -DXMSS_VERIFY_ONLY"
|
||||
;;
|
||||
wolfssl)
|
||||
ENABLED_WC_XMSS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_XMSS"
|
||||
;;
|
||||
small)
|
||||
ENABLED_WC_XMSS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_XMSS_SMALL"
|
||||
;;
|
||||
*)
|
||||
@@ -1255,20 +1248,6 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
if test "$ENABLED_XMSS" != "no"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_XMSS"
|
||||
|
||||
if test "$ENABLED_WC_XMSS" = "no";
|
||||
then
|
||||
# Default is to use hash-sigs XMSS lib. Make sure it's enabled.
|
||||
if test "$ENABLED_LIBXMSS" = "no"; then
|
||||
AC_MSG_ERROR([The default implementation for XMSS is the xmss-reference lib.
|
||||
Please use --with-libxmss.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# libxmss
|
||||
# Get the path to xmss-reference.
|
||||
ENABLED_LIBXMSS="no"
|
||||
@@ -1321,6 +1300,19 @@ AC_ARG_WITH([libxmss],
|
||||
[XMSS_ROOT=""]
|
||||
)
|
||||
|
||||
if test "$ENABLED_XMSS" != "no"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_XMSS"
|
||||
|
||||
# Use hash-sigs XMSS lib if enabled.
|
||||
if test "$ENABLED_LIBXMSS" = "yes"; then
|
||||
ENABLED_WC_XMSS=no
|
||||
else
|
||||
ENABLED_WC_XMSS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_XMSS"
|
||||
fi
|
||||
fi
|
||||
|
||||
# LMS
|
||||
AC_ARG_ENABLE([lms],
|
||||
[AS_HELP_STRING([--enable-lms],[Enable stateful LMS/HSS signatures (default: disabled)])],
|
||||
@@ -1328,7 +1320,6 @@ AC_ARG_ENABLE([lms],
|
||||
[ ENABLED_LMS=no ]
|
||||
)
|
||||
|
||||
ENABLED_WC_LMS=no
|
||||
for v in `echo $ENABLED_LMS | tr "," " "`
|
||||
do
|
||||
case $v in
|
||||
@@ -1337,37 +1328,17 @@ do
|
||||
no)
|
||||
;;
|
||||
verify-only)
|
||||
LMS_VERIFY_ONLY=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_VERIFY_ONLY"
|
||||
;;
|
||||
small)
|
||||
ENABLED_WC_LMS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_LMS_SMALL"
|
||||
;;
|
||||
wolfssl)
|
||||
ENABLED_WC_LMS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_LMS"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid choice for LMS []: $ENABLED_LMS.])
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test "$ENABLED_LMS" != "no"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_LMS"
|
||||
|
||||
if test "$ENABLED_WC_LMS" = "no";
|
||||
then
|
||||
# Default is to use hash-sigs LMS lib. Make sure it's enabled.
|
||||
if test "$ENABLED_LIBLMS" = "no"; then
|
||||
AC_MSG_ERROR([The default implementation for LMS is the hash-sigs LMS/HSS lib.
|
||||
Please use --with-liblms.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# liblms
|
||||
# Get the path to the hash-sigs LMS HSS lib.
|
||||
ENABLED_LIBLMS="no"
|
||||
@@ -1436,6 +1407,19 @@ AC_ARG_WITH([liblms],
|
||||
]
|
||||
)
|
||||
|
||||
if test "$ENABLED_LMS" != "no"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_LMS"
|
||||
|
||||
# Use hash-sigs LMS lib if enabled.
|
||||
if test "$ENABLED_LIBLMS" = "yes"; then
|
||||
ENABLED_WC_LMS=no
|
||||
else
|
||||
ENABLED_WC_LMS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_LMS"
|
||||
fi
|
||||
fi
|
||||
|
||||
# SINGLE THREADED
|
||||
AC_ARG_ENABLE([singlethreaded],
|
||||
[AS_HELP_STRING([--enable-singlethreaded],[Enable wolfSSL single threaded (default: disabled)])],
|
||||
|
||||
+1123
-4
File diff suppressed because it is too large
Load Diff
+3069
-3
File diff suppressed because it is too large
Load Diff
+1643
-1
File diff suppressed because it is too large
Load Diff
+4315
-3
File diff suppressed because it is too large
Load Diff
+448
-1
@@ -19,5 +19,452 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#error "Contact wolfSSL to get the implementation of this file"
|
||||
/* Implementation based on:
|
||||
* RFC 8554: Leighton-Micali Hash-Based Signatures
|
||||
* https://datatracker.ietf.org/doc/html/rfc8554
|
||||
* Implementation by Sean Parkinson.
|
||||
*/
|
||||
|
||||
/* Possible LMS options:
|
||||
*
|
||||
* WOLFSSL_LMS_LARGE_CACHES Default: OFF
|
||||
* Authentication path caches are large and signing faster.
|
||||
* WOLFSSL_LMS_ROOT_LEVELS Default: 5 (Large: 7)
|
||||
* Number of levels of interior nodes from the to to cached.
|
||||
* Valid value are: 1..height of subtree.
|
||||
* The bigger the number, the larger the LmsKey but faster signing.
|
||||
* Only applies when !WOLFSSL_WC_LMS_SMALL.
|
||||
* WOLFSSL_LMS_CACHE_BITS Default: 5 (Large: 7)
|
||||
* 2 to the power of the value is the number of leaf nodes to cache.
|
||||
* Maximum valid value is height of subtree.
|
||||
* Valid value are: 0..height of subtree.
|
||||
* The bigger the number, the larger the LmsKey but faster signing.
|
||||
* Only applies when !WOLFSSL_WC_LMS_SMALL.
|
||||
*
|
||||
* Memory/Level | R/C | Approx. Time (% of 5/5)
|
||||
* (Bytes) | | H=10 | H=15 | H=20
|
||||
* -------------+--------------+--------+--------
|
||||
* 2016 | 5/5 | 100.0% | 100.0% | 100.0%
|
||||
* 3040 | 5/6 | 75.5% | 89.2% |
|
||||
* 4064 | 6/6 | 75.3% | 78.8% |
|
||||
* 4576 | 4/7 | 72.4% | 87.6% |
|
||||
* 6112 | 6/7 | 72.1% | 67.5% |
|
||||
* 8160 | 7/7 | 72.2% | 56.8% |
|
||||
* 8416 | 3/8 | 66.4% | 84.9% |
|
||||
* 12256 | 7/8 | 66.5% | 45.9% |
|
||||
* 16352 | 8/8 | 66.0% | 35.0% |
|
||||
* 16416 | 1/9 | 54.1% | 79.5% |
|
||||
* R = Root levels
|
||||
* C = Cache bits
|
||||
* To mimic the dynamic memory usage of XMSS, use 3/3.
|
||||
*
|
||||
* WOLFSSL_LMS_NO_SIGN SMOOTHING Default: OFF
|
||||
* Disable precalculation of next subtree.
|
||||
* Use less dynamic memory.
|
||||
* At certain indexes, signing will take a long time compared to the mean.
|
||||
* When OFF, the private key holds a second copy of caches.
|
||||
*
|
||||
* WOLFSSL_LMS_NO_SIG_CACHE Default: OFF
|
||||
* Signature cache is disabled.
|
||||
* This will use less dynamic memory and make signing slower when multiple
|
||||
* levels.
|
||||
*
|
||||
* Sig cache holds the C and y hashes for a tree that is not the lowest.
|
||||
* Sig cache size = (levels - 1) * (1 + p) * 32 bytes
|
||||
* p is the number of y terms based on Winternitz width.
|
||||
*
|
||||
* w | p | l | Bytes
|
||||
* ---+----+---+------
|
||||
* 4 | 67 | 2 | 2176
|
||||
* 4 | 67 | 3 | 4353
|
||||
* 4 | 67 | 4 | 6528
|
||||
* 8 | 34 | 2 | 1120
|
||||
* 8 | 34 | 3 | 2240
|
||||
* 8 | 34 | 4 | 3360
|
||||
* w = Winternitz width
|
||||
* l = #levels
|
||||
*/
|
||||
|
||||
#ifndef WC_LMS_H
|
||||
#define WC_LMS_H
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS) && defined(WOLFSSL_WC_LMS)
|
||||
|
||||
#include <wolfssl/wolfcrypt/lms.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
|
||||
#ifdef WOLFSSL_LMS_MAX_LEVELS
|
||||
/* Maximum number of levels of trees supported by implementation. */
|
||||
#define LMS_MAX_LEVELS WOLFSSL_LMS_MAX_LEVELS
|
||||
#else
|
||||
/* Maximum number of levels of trees supported by implementation. */
|
||||
#define LMS_MAX_LEVELS 4
|
||||
#endif
|
||||
#if (LMS_MAX_LEVELS < 1) || (LMS_MAX_LEVELS > 4)
|
||||
#error "LMS parameters only support heights 1-4."
|
||||
#endif
|
||||
|
||||
/* Smoothing is only used when there are 2 or more levels. */
|
||||
#if LMS_MAX_LEVELS == 1 && !defined(WOLFSSL_LMS_NO_SIGN_SMOOTHING)
|
||||
#define WOLFSSL_LMS_NO_SIGN_SMOOTHING
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_LMS_MAX_HEIGHT
|
||||
/* Maximum height of a tree supported by implementation. */
|
||||
#define LMS_MAX_HEIGHT WOLFSSL_LMS_MAX_HEIGHT
|
||||
#else
|
||||
/* Maximum height of a tree supported by implementation. */
|
||||
#define LMS_MAX_HEIGHT 20
|
||||
#endif
|
||||
#if (LMS_MAX_HEIGHT < 5) || (LMS_MAX_HEIGHT > 20)
|
||||
#error "LMS parameters only support heights 5-20."
|
||||
#endif
|
||||
|
||||
/* Length of I in bytes. */
|
||||
#define LMS_I_LEN 16
|
||||
/* Length of L in bytes. */
|
||||
#define LMS_L_LEN 4
|
||||
/* Length of Q for a level. */
|
||||
#define LMS_Q_LEN 4
|
||||
/* Length of P in bytes. */
|
||||
#define LMS_P_LEN 2
|
||||
/* Length of W in bytes. */
|
||||
#define LMS_W_LEN 1
|
||||
|
||||
/* Length of numeric types when encoding. */
|
||||
#define LMS_TYPE_LEN 4
|
||||
|
||||
/* Maximum size of a node hash. */
|
||||
#define LMS_MAX_NODE_LEN WC_SHA256_DIGEST_SIZE
|
||||
/* Maximum size of SEED (produced by hash). */
|
||||
#define LMS_SEED_LEN WC_SHA256_DIGEST_SIZE
|
||||
/* Maximum number of P, number of n-byte string elements in LM-OTS signature.
|
||||
* Value of P when N=32 and W=1.
|
||||
*/
|
||||
#define LMS_MAX_P 265
|
||||
/* Length of SEED and I in bytes. */
|
||||
#define LMS_SEED_I_LEN (LMS_SEED_LEN + LMS_I_LEN)
|
||||
|
||||
|
||||
#ifndef WOLFSSL_LMS_ROOT_LEVELS
|
||||
#ifdef WOLFSSL_LMS_LARGE_CACHES
|
||||
/* Number of root levels of interior nodes to store. */
|
||||
#define LMS_ROOT_LEVELS 7
|
||||
#else
|
||||
/* Number of root levels of interior nodes to store. */
|
||||
#define LMS_ROOT_LEVELS 5
|
||||
#endif
|
||||
#else
|
||||
#define LMS_ROOT_LEVELS WOLFSSL_LMS_ROOT_LEVELS
|
||||
#endif
|
||||
#if LMS_ROOT_LEVELS <= 0
|
||||
#error "LMS_ROOT_LEVELS must be greater than 0."
|
||||
#endif
|
||||
/* Count of root nodes to store per level. */
|
||||
#define LMS_ROOT_COUNT ((1 << (LMS_ROOT_LEVELS)) - 1)
|
||||
|
||||
#ifndef WOLFSSL_LMS_CACHE_BITS
|
||||
#ifdef WOLFSSL_LMS_LARGE_CACHES
|
||||
/* 2 to the power of the value is the number of leaf nodes to cache. */
|
||||
#define LMS_CACHE_BITS 7
|
||||
#else
|
||||
/* 2 to the power of the value is the number of leaf nodes to cache. */
|
||||
#define LMS_CACHE_BITS 5
|
||||
#endif
|
||||
#else
|
||||
#define LMS_CACHE_BITS WOLFSSL_LMS_CACHE_BITS
|
||||
#endif
|
||||
#if LMS_CACHE_BITS < 0
|
||||
#error "LMS_CACHE_BITS must be greater than or equal to 0."
|
||||
#endif
|
||||
/* Number of leaf nodes to cache. */
|
||||
#define LMS_LEAF_CACHE (1 << LMS_CACHE_BITS)
|
||||
|
||||
/* Maximum number of levels of trees described in private key. */
|
||||
#define HSS_MAX_LEVELS 8
|
||||
/* Length of full Q in bytes. Q from all levels combined. */
|
||||
#define HSS_Q_LEN 8
|
||||
|
||||
/* Compressed parameter set length in bytes. */
|
||||
#define HSS_COMPRESS_PARAM_SET_LEN 1
|
||||
/* Total compressed parameter set length for private key in bytes. */
|
||||
#define HSS_PRIV_KEY_PARAM_SET_LEN \
|
||||
(HSS_COMPRESS_PARAM_SET_LEN * HSS_MAX_LEVELS)
|
||||
|
||||
/* Private key length for one level. */
|
||||
#define LMS_PRIV_LEN \
|
||||
(LMS_Q_LEN + LMS_SEED_LEN + LMS_I_LEN)
|
||||
/* Public key length in signature. */
|
||||
#define LMS_PUBKEY_LEN \
|
||||
(LMS_TYPE_LEN + LMS_TYPE_LEN + LMS_I_LEN + LMS_MAX_NODE_LEN)
|
||||
|
||||
/* LMS signature data length. */
|
||||
#define LMS_SIG_LEN(h, p) \
|
||||
(LMS_Q_LEN + LMS_TYPE_LEN + LMS_MAX_NODE_LEN + (p) * LMS_MAX_NODE_LEN + \
|
||||
LMS_TYPE_LEN + (h) * LMS_MAX_NODE_LEN)
|
||||
|
||||
/* Length of public key. */
|
||||
#define HSS_PUBLIC_KEY_LEN (LMS_L_LEN + LMS_PUBKEY_LEN)
|
||||
/* Length of private key. */
|
||||
#define HSS_PRIVATE_KEY_LEN \
|
||||
(HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + LMS_SEED_LEN + LMS_I_LEN)
|
||||
/* Maximum public key length - length is constant for all parameters. */
|
||||
#define HSS_MAX_PRIVATE_KEY_LEN HSS_PRIVATE_KEY_LEN
|
||||
/* Maximum private key length - length is constant for all parameters. */
|
||||
#define HSS_MAX_PUBLIC_KEY_LEN HSS_PUBLIC_KEY_LEN
|
||||
/* Maximum signature length. */
|
||||
#define HSS_MAX_SIG_LEN \
|
||||
(LMS_TYPE_LEN + \
|
||||
LMS_MAX_LEVELS * (LMS_Q_LEN + LMS_TYPE_LEN + LMS_TYPE_LEN + \
|
||||
LMS_MAX_NODE_LEN * (1 + LMS_MAX_P + LMS_MAX_HEIGHT)) + \
|
||||
(LMS_MAX_LEVELS - 1) * LMS_PUBKEY_LEN \
|
||||
)
|
||||
|
||||
/* Maximum buffer length required for use when hashing. */
|
||||
#define LMS_MAX_BUFFER_LEN \
|
||||
(LMS_I_LEN + LMS_Q_LEN + LMS_P_LEN + LMS_W_LEN + 2 * LMS_MAX_NODE_LEN)
|
||||
|
||||
|
||||
/* Private key data length.
|
||||
*
|
||||
* HSSPrivKey.priv
|
||||
*/
|
||||
#define LMS_PRIV_KEY_LEN(l) \
|
||||
((l) * LMS_PRIV_LEN)
|
||||
|
||||
/* Stack of nodes. */
|
||||
#define LMS_STACK_CACHE_LEN(h) \
|
||||
(((h) + 1) * LMS_MAX_NODE_LEN)
|
||||
|
||||
/* Root cache length. */
|
||||
#define LMS_ROOT_CACHE_LEN(rl) \
|
||||
(((1 << (rl)) - 1) * LMS_MAX_NODE_LEN)
|
||||
|
||||
/* Leaf cache length. */
|
||||
#define LMS_LEAF_CACHE_LEN(cb) \
|
||||
((1 << (cb)) * LMS_MAX_NODE_LEN)
|
||||
|
||||
/* Length of LMS private key state.
|
||||
*
|
||||
* LmsPrivState
|
||||
* auth_path +
|
||||
* root +
|
||||
* stack.stack + stack.offset +
|
||||
* cache.leaf + cache.index + cache.offset
|
||||
*/
|
||||
#define LMS_PRIV_STATE_LEN(h, rl, cb) \
|
||||
(((h) * LMS_MAX_NODE_LEN) + \
|
||||
LMS_STACK_CACHE_LEN(h) + 4 + \
|
||||
LMS_ROOT_CACHE_LEN(rl) + \
|
||||
LMS_LEAF_CACHE_LEN(cb) + 4 + 4)
|
||||
|
||||
#ifndef WOLFSSL_WC_LMS_SMALL
|
||||
/* Private key data state for all levels. */
|
||||
#define LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb) \
|
||||
((l) * LMS_PRIV_STATE_LEN(h, rl, cb))
|
||||
#else
|
||||
/* Private key data state for all levels. */
|
||||
#define LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb) 0
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_LMS_NO_SIGN_SMOOTHING
|
||||
/* Extra private key data for smoothing. */
|
||||
#define LMS_PRIV_SMOOTH_LEN(l, h, rl, cb) \
|
||||
(LMS_PRIV_KEY_LEN(l) + \
|
||||
((l) - 1) * LMS_PRIV_STATE_LEN(h, rl, cb))
|
||||
#else
|
||||
/* Extra private key data for smoothing. */
|
||||
#define LMS_PRIV_SMOOTH_LEN(l, h, rl, cb) 0
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_LMS_NO_SIG_CACHE
|
||||
#define LMS_PRIV_Y_TREE_LEN(p) \
|
||||
(LMS_MAX_NODE_LEN + (p) * LMS_MAX_NODE_LEN)
|
||||
/* Length of the y data cached in private key data. */
|
||||
#define LMS_PRIV_Y_LEN(l, p) \
|
||||
(((l) - 1) * (LMS_MAX_NODE_LEN + (p) * LMS_MAX_NODE_LEN))
|
||||
#else
|
||||
/* Length of the y data cached in private key data. */
|
||||
#define LMS_PRIV_Y_LEN(l, p) 0
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_WC_LMS_SMALL
|
||||
/* Length of private key data. */
|
||||
#define LMS_PRIV_DATA_LEN(l, h, p, rl, cb) \
|
||||
(LMS_PRIV_KEY_LEN(l) + \
|
||||
LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb) + \
|
||||
LMS_PRIV_SMOOTH_LEN(l, h, rl, cb) + \
|
||||
LMS_PRIV_Y_LEN(l, p))
|
||||
#else
|
||||
#define LMS_PRIV_DATA_LEN(l, h, p, rl, cb) \
|
||||
LMS_PRIV_KEY_LEN(l)
|
||||
#endif
|
||||
|
||||
|
||||
/* LMS Parameters. */
|
||||
/* SHA-256 hash, 32-bytes of hash used, tree height of 5. */
|
||||
#define LMS_SHA256_M32_H5 5
|
||||
/* SHA-256 hash, 32-bytes of hash used, tree height of 10. */
|
||||
#define LMS_SHA256_M32_H10 6
|
||||
/* SHA-256 hash, 32-bytes of hash used, tree height of 15. */
|
||||
#define LMS_SHA256_M32_H15 7
|
||||
/* SHA-256 hash, 32-bytes of hash used, tree height of 20. */
|
||||
#define LMS_SHA256_M32_H20 8
|
||||
/* SHA-256 hash, 32-bytes of hash used, tree height of 25. */
|
||||
#define LMS_SHA256_M32_H25 9
|
||||
|
||||
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 1 bit. */
|
||||
#define LMOTS_SHA256_N32_W1 1
|
||||
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 2 bits. */
|
||||
#define LMOTS_SHA256_N32_W2 2
|
||||
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 4 bits. */
|
||||
#define LMOTS_SHA256_N32_W4 3
|
||||
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 8 bits. */
|
||||
#define LMOTS_SHA256_N32_W8 4
|
||||
|
||||
typedef struct LmsParams {
|
||||
/* Number of tree levels. */
|
||||
word8 levels;
|
||||
/* Height of each tree. */
|
||||
word8 height;
|
||||
/* Width or Winternitz coefficient. */
|
||||
word8 width;
|
||||
/* Number of left-shift bits used in checksum calculation. */
|
||||
word8 ls;
|
||||
/* Number of n-byte string elements in LM-OTS signature. */
|
||||
word16 p;
|
||||
/* LMS type. */
|
||||
word16 lmsType;
|
||||
/* LMOTS type. */
|
||||
word16 lmOtsType;
|
||||
/* Length of LM-OTS signature. */
|
||||
word16 sig_len;
|
||||
#ifndef WOLFSSL_WC_LMS_SMALL
|
||||
/* Number of root levels of interior nodes to store. */
|
||||
word8 rootLevels;
|
||||
/* 2 to the power of the value is the number of leaf nodes to cache. */
|
||||
word8 cacheBits;
|
||||
#endif
|
||||
} LmsParams;
|
||||
|
||||
/* Mapping of id and string to parameters. */
|
||||
typedef struct wc_LmsParamsMap {
|
||||
/* Identifier of parameters. */
|
||||
enum wc_LmsParm id;
|
||||
/* String representation of identifier of parameters. */
|
||||
const char* str;
|
||||
/* LMS parameter set. */
|
||||
LmsParams params;
|
||||
} wc_LmsParamsMap;
|
||||
|
||||
typedef struct LmsState {
|
||||
/* Buffer to hold data to hash. */
|
||||
ALIGN16 byte buffer[LMS_MAX_BUFFER_LEN];
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
/* Buffer to hold expanded Q coefficients. */
|
||||
ALIGN16 byte a[LMS_MAX_P];
|
||||
#endif
|
||||
/* LMS parameters. */
|
||||
const LmsParams* params;
|
||||
/* Hash algorithm. */
|
||||
wc_Sha256 hash;
|
||||
/* Hash algorithm for calculating K. */
|
||||
wc_Sha256 hash_k;
|
||||
} LmsState;
|
||||
|
||||
#ifndef WOLFSSL_WC_LMS_SMALL
|
||||
/* Stack of interior node hashes. */
|
||||
typedef struct LmsStack {
|
||||
/* Stack nodes. */
|
||||
byte* stack;
|
||||
/* Top of stack offset. */
|
||||
word32 offset;
|
||||
} LmsStack;
|
||||
|
||||
/* Cache of leaf hashes. */
|
||||
typedef struct HssLeafCache {
|
||||
/* Cache of leaf nodes. Circular queue. */
|
||||
byte* cache;
|
||||
/* Start index of cached leaf nodes. */
|
||||
word32 idx;
|
||||
/* Index into cache of first leaf node. */
|
||||
word32 offset;
|
||||
} HssLeafCache;
|
||||
|
||||
typedef struct LmsPrivState {
|
||||
/* Authentication path for current index. */
|
||||
byte* auth_path;
|
||||
/* Stack nodes. */
|
||||
LmsStack stack;
|
||||
/* Root nodes. */
|
||||
byte* root;
|
||||
/* Cache of leaf nodes. */
|
||||
HssLeafCache leaf;
|
||||
} LmsPrivState;
|
||||
#endif /* WOLFSSL_WC_LMS_SMALL */
|
||||
|
||||
typedef struct HssPrivKey {
|
||||
/* Private key. */
|
||||
byte* priv;
|
||||
#ifndef WOLFSSL_WC_LMS_SMALL
|
||||
/* Per level state of the private key. */
|
||||
LmsPrivState state[LMS_MAX_LEVELS];
|
||||
#ifndef WOLFSSL_LMS_NO_SIGN_SMOOTHING
|
||||
/* Next private key. */
|
||||
byte* next_priv;
|
||||
/* Next private state. */
|
||||
LmsPrivState next_state[LMS_MAX_LEVELS - 1];
|
||||
#endif
|
||||
#ifndef WOLFSSL_LMS_NO_SIG_CACHE
|
||||
/* Per level state of the private key. */
|
||||
byte* y;
|
||||
#endif
|
||||
/* Indicates the key has all levels initialized. */
|
||||
word8 inited:1;
|
||||
#endif
|
||||
} HssPrivKey;
|
||||
|
||||
struct LmsKey {
|
||||
/* Public key. */
|
||||
ALIGN16 byte pub[HSS_PUBLIC_KEY_LEN];
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
/* Encoded private key. */
|
||||
ALIGN16 byte priv_raw[HSS_PRIVATE_KEY_LEN];
|
||||
|
||||
/* Packed private key data. */
|
||||
byte* priv_data;
|
||||
/* HSS Private key. */
|
||||
HssPrivKey priv;
|
||||
|
||||
/* Callback to write/update key. */
|
||||
wc_lms_write_private_key_cb write_private_key;
|
||||
/* Callback to read key. */
|
||||
wc_lms_read_private_key_cb read_private_key;
|
||||
/* Context arg passed to callbacks. */
|
||||
void* context;
|
||||
/* Dynamic memory hint. */
|
||||
void* heap;
|
||||
#endif /* !WOLFSSL_LMS_VERIFY_ONLY */
|
||||
/* Parameters of key. */
|
||||
const LmsParams* params;
|
||||
/* Current state of key. */
|
||||
enum wc_LmsState state;
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
/* Device Identifier. */
|
||||
int devId;
|
||||
#endif
|
||||
};
|
||||
|
||||
int wc_hss_make_key(LmsState* state, WC_RNG* rng, byte* priv_raw,
|
||||
HssPrivKey* priv_key, byte* priv_data, byte* pub);
|
||||
int wc_hss_reload_key(LmsState* state, const byte* priv_raw,
|
||||
HssPrivKey* priv_key, byte* priv_data, byte* pub_root);
|
||||
int wc_hss_sign(LmsState* state, byte* priv_raw, HssPrivKey* priv_key,
|
||||
byte* priv_data, const byte* msg, word32 msgSz, byte* sig);
|
||||
int wc_hss_sigsleft(const LmsParams* params, const byte* priv_raw);
|
||||
int wc_hss_verify(LmsState* state, const byte* pub, const byte* msg,
|
||||
word32 msgSz, const byte* sig);
|
||||
|
||||
#endif /* WOLFSSL_HAVE_LMS && WOLFSSL_WC_LMS */
|
||||
|
||||
#endif /* WC_LMS_H */
|
||||
|
||||
+263
-1
@@ -19,5 +19,267 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#error "Contact wolfSSL to get the implementation of this file"
|
||||
/* Based on:
|
||||
* o RFC 8391 - XMSS: eXtended Merkle Signature Scheme
|
||||
* o [HDSS] "Hash-based Digital Signature Schemes", Buchmann, Dahmen and Szydlo
|
||||
* from "Post Quantum Cryptography", Springer 2009.
|
||||
*/
|
||||
|
||||
#ifndef WC_XMSS_H
|
||||
#define WC_XMSS_H
|
||||
|
||||
#ifdef WOLFSSL_HAVE_XMSS
|
||||
#include <wolfssl/wolfcrypt/xmss.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/sha512.h>
|
||||
#include <wolfssl/wolfcrypt/sha3.h>
|
||||
|
||||
#if !defined(WOLFSSL_WC_XMSS)
|
||||
#error "This code is incompatible with external implementation of XMSS."
|
||||
#endif
|
||||
|
||||
#if (defined(WC_XMSS_SHA512) || defined(WC_XMSS_SHAKE256)) && \
|
||||
(WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512)
|
||||
#define WC_XMSS_MAX_N 64
|
||||
#define WC_XMSS_MAX_PADDING_LEN 64
|
||||
#else
|
||||
#define WC_XMSS_MAX_N 32
|
||||
#define WC_XMSS_MAX_PADDING_LEN 32
|
||||
#endif
|
||||
#define WC_XMSS_MAX_MSG_PRE_LEN \
|
||||
(WC_XMSS_MAX_PADDING_LEN + 3 * WC_XMSS_MAX_N)
|
||||
#define WC_XMSS_MAX_TREE_HEIGHT 20
|
||||
#define WC_XMSS_MAX_CSUM_BYTES 4
|
||||
#define WC_XMSS_MAX_WOTS_LEN (8 * WC_XMSS_MAX_N / 4 + 3)
|
||||
#define WC_XMSS_MAX_WOTS_SIG_LEN (WC_XMSS_MAX_WOTS_LEN * WC_XMSS_MAX_N)
|
||||
#define WC_XMSS_MAX_STACK_LEN \
|
||||
((WC_XMSS_MAX_TREE_HEIGHT + 1) * WC_XMSS_MAX_N)
|
||||
#define WC_XMSS_MAX_D 12
|
||||
#define WC_XMSS_MAX_BDS_STATES (2 * WC_XMSS_MAX_D - 1)
|
||||
#define WC_XMSS_MAX_TREE_HASH \
|
||||
((2 * WC_XMSS_MAX_D - 1) * WC_XMSS_MAX_TREE_HEIGHT)
|
||||
#define WC_XMSS_MAX_BDS_K 0
|
||||
|
||||
#define WC_XMSS_ADDR_LEN 32
|
||||
|
||||
#define WC_XMSS_HASH_PRF_MAX_DATA_LEN \
|
||||
(WC_XMSS_MAX_PADDING_LEN + 2 * WC_XMSS_MAX_N + WC_XMSS_ADDR_LEN)
|
||||
#define WC_XMSS_HASH_MAX_DATA_LEN \
|
||||
(WC_XMSS_MAX_PADDING_LEN + 3 * WC_XMSS_MAX_N)
|
||||
|
||||
|
||||
#define WC_XMSS_SHA256_N 32
|
||||
#define WC_XMSS_SHA256_PADDING_LEN 32
|
||||
#define WC_XMSS_SHA256_WOTS_LEN 67
|
||||
|
||||
#define XMSS_OID_LEN 4
|
||||
|
||||
#define XMSS_MAX_HASH_LEN WC_SHA256_DIGEST_SIZE
|
||||
|
||||
#define XMSS_RETAIN_LEN(k, n) ((!!(k)) * ((1 << (k)) - (k) - 1) * (n))
|
||||
|
||||
/* XMMS Algorithm OIDs
|
||||
* Note: values are used in mathematical calculations in OID to parames. */
|
||||
#define WC_XMSS_OID_SHA2_10_256 0x01
|
||||
#define WC_XMSS_OID_SHA2_16_256 0x02
|
||||
#define WC_XMSS_OID_SHA2_20_256 0x03
|
||||
#define WC_XMSS_OID_SHA2_10_512 0x04
|
||||
#define WC_XMSS_OID_SHA2_16_512 0x05
|
||||
#define WC_XMSS_OID_SHA2_20_512 0x06
|
||||
#define WC_XMSS_OID_SHAKE_10_256 0x07
|
||||
#define WC_XMSS_OID_SHAKE_16_256 0x08
|
||||
#define WC_XMSS_OID_SHAKE_20_256 0x09
|
||||
#define WC_XMSS_OID_SHAKE_10_512 0x0a
|
||||
#define WC_XMSS_OID_SHAKE_16_512 0x0b
|
||||
#define WC_XMSS_OID_SHAKE_20_512 0x0c
|
||||
#define WC_XMSS_OID_SHA2_10_192 0x0d
|
||||
#define WC_XMSS_OID_SHA2_16_192 0x0e
|
||||
#define WC_XMSS_OID_SHA2_20_192 0x0f
|
||||
#define WC_XMSS_OID_SHAKE256_10_256 0x10
|
||||
#define WC_XMSS_OID_SHAKE256_16_256 0x11
|
||||
#define WC_XMSS_OID_SHAKE256_20_256 0x12
|
||||
#define WC_XMSS_OID_SHAKE256_10_192 0x13
|
||||
#define WC_XMSS_OID_SHAKE256_16_192 0x14
|
||||
#define WC_XMSS_OID_SHAKE256_20_192 0x15
|
||||
#define WC_XMSS_OID_FIRST WC_XMSS_OID_SHA2_10_256
|
||||
#define WC_XMSS_OID_LAST WC_XMSS_OID_SHAKE256_20_192
|
||||
|
||||
/* XMMS^MT Algorithm OIDs
|
||||
* Note: values are used in mathematical calculations in OID to parames. */
|
||||
#define WC_XMSSMT_OID_SHA2_20_2_256 0x01
|
||||
#define WC_XMSSMT_OID_SHA2_20_4_256 0x02
|
||||
#define WC_XMSSMT_OID_SHA2_40_2_256 0x03
|
||||
#define WC_XMSSMT_OID_SHA2_40_4_256 0x04
|
||||
#define WC_XMSSMT_OID_SHA2_40_8_256 0x05
|
||||
#define WC_XMSSMT_OID_SHA2_60_3_256 0x06
|
||||
#define WC_XMSSMT_OID_SHA2_60_6_256 0x07
|
||||
#define WC_XMSSMT_OID_SHA2_60_12_256 0x08
|
||||
#define WC_XMSSMT_OID_SHA2_20_2_512 0x09
|
||||
#define WC_XMSSMT_OID_SHA2_20_4_512 0x0a
|
||||
#define WC_XMSSMT_OID_SHA2_40_2_512 0x0b
|
||||
#define WC_XMSSMT_OID_SHA2_40_4_512 0x0c
|
||||
#define WC_XMSSMT_OID_SHA2_40_8_512 0x0d
|
||||
#define WC_XMSSMT_OID_SHA2_60_3_512 0x0e
|
||||
#define WC_XMSSMT_OID_SHA2_60_6_512 0x0f
|
||||
#define WC_XMSSMT_OID_SHA2_60_12_512 0x10
|
||||
#define WC_XMSSMT_OID_SHAKE_20_2_256 0x11
|
||||
#define WC_XMSSMT_OID_SHAKE_20_4_256 0x12
|
||||
#define WC_XMSSMT_OID_SHAKE_40_2_256 0x13
|
||||
#define WC_XMSSMT_OID_SHAKE_40_4_256 0x14
|
||||
#define WC_XMSSMT_OID_SHAKE_40_8_256 0x15
|
||||
#define WC_XMSSMT_OID_SHAKE_60_3_256 0x16
|
||||
#define WC_XMSSMT_OID_SHAKE_60_6_256 0x17
|
||||
#define WC_XMSSMT_OID_SHAKE_60_12_256 0x18
|
||||
#define WC_XMSSMT_OID_SHAKE_20_2_512 0x19
|
||||
#define WC_XMSSMT_OID_SHAKE_20_4_512 0x1a
|
||||
#define WC_XMSSMT_OID_SHAKE_40_2_512 0x1b
|
||||
#define WC_XMSSMT_OID_SHAKE_40_4_512 0x1c
|
||||
#define WC_XMSSMT_OID_SHAKE_40_8_512 0x1d
|
||||
#define WC_XMSSMT_OID_SHAKE_60_3_512 0x1e
|
||||
#define WC_XMSSMT_OID_SHAKE_60_6_512 0x1f
|
||||
#define WC_XMSSMT_OID_SHAKE_60_12_512 0x20
|
||||
#define WC_XMSSMT_OID_SHA2_20_2_192 0x21
|
||||
#define WC_XMSSMT_OID_SHA2_20_4_192 0x22
|
||||
#define WC_XMSSMT_OID_SHA2_40_2_192 0x23
|
||||
#define WC_XMSSMT_OID_SHA2_40_4_192 0x24
|
||||
#define WC_XMSSMT_OID_SHA2_40_8_192 0x25
|
||||
#define WC_XMSSMT_OID_SHA2_60_3_192 0x26
|
||||
#define WC_XMSSMT_OID_SHA2_60_6_192 0x27
|
||||
#define WC_XMSSMT_OID_SHA2_60_12_192 0x28
|
||||
#define WC_XMSSMT_OID_SHAKE256_20_2_256 0x29
|
||||
#define WC_XMSSMT_OID_SHAKE256_20_4_256 0x2a
|
||||
#define WC_XMSSMT_OID_SHAKE256_40_2_256 0x2b
|
||||
#define WC_XMSSMT_OID_SHAKE256_40_4_256 0x2c
|
||||
#define WC_XMSSMT_OID_SHAKE256_40_8_256 0x2d
|
||||
#define WC_XMSSMT_OID_SHAKE256_60_3_256 0x2e
|
||||
#define WC_XMSSMT_OID_SHAKE256_60_6_256 0x2f
|
||||
#define WC_XMSSMT_OID_SHAKE256_60_12_256 0x30
|
||||
#define WC_XMSSMT_OID_SHAKE256_20_2_192 0x31
|
||||
#define WC_XMSSMT_OID_SHAKE256_20_4_192 0x32
|
||||
#define WC_XMSSMT_OID_SHAKE256_40_2_192 0x33
|
||||
#define WC_XMSSMT_OID_SHAKE256_40_4_192 0x34
|
||||
#define WC_XMSSMT_OID_SHAKE256_40_8_192 0x35
|
||||
#define WC_XMSSMT_OID_SHAKE256_60_3_192 0x36
|
||||
#define WC_XMSSMT_OID_SHAKE256_60_6_192 0x37
|
||||
#define WC_XMSSMT_OID_SHAKE256_60_12_192 0x38
|
||||
#define WC_XMSSMT_OID_FIRST WC_XMSSMT_OID_SHA2_20_2_256
|
||||
#define WC_XMSSMT_OID_LAST WC_XMSSMT_OID_SHAKE256_60_12_192
|
||||
|
||||
|
||||
/* Type for hash address. */
|
||||
typedef word32 HashAddress[8];
|
||||
|
||||
/* XMSS/XMSS^MT fixed parameters. */
|
||||
typedef struct XmssParams {
|
||||
/* Hash algorithm to use. */
|
||||
word8 hash;
|
||||
/* Size of hash output. */
|
||||
word8 n;
|
||||
/* Number of bytes of padding before rest of hash data. */
|
||||
word8 pad_len;
|
||||
/* Number of values to chain = 2 * n + 3. */
|
||||
word8 wots_len;
|
||||
/* Number of bytes in each WOTS+ signature. */
|
||||
word16 wots_sig_len;
|
||||
/* Full height of tree. */
|
||||
word8 h;
|
||||
/* Height of tree each subtree. */
|
||||
word8 sub_h;
|
||||
/* Number of subtrees = h / sub_h. */
|
||||
word8 d;
|
||||
/* Number of bytes to encode index into in private/secret key. */
|
||||
word8 idx_len;
|
||||
/* Number of bytes in a signature. */
|
||||
word32 sig_len;
|
||||
/* Number of bytes in a secret/private key. */
|
||||
word32 sk_len;
|
||||
/* Number of bytes in a public key. */
|
||||
word8 pk_len;
|
||||
/* BDS parameter for fast C implementation. */
|
||||
word8 bds_k;
|
||||
} XmssParams;
|
||||
|
||||
struct XmssKey {
|
||||
/* Public key. */
|
||||
unsigned char pk[2 * WC_XMSS_MAX_N];
|
||||
/* OID that identifies parameters. */
|
||||
word32 oid;
|
||||
/* Indicates whether the parameters are for XMSS^MT. */
|
||||
int is_xmssmt;
|
||||
/* XMSS/XMSS^MT parameters. */
|
||||
const XmssParams* params;
|
||||
#ifndef WOLFSSL_XMSS_VERIFY_ONLY
|
||||
/* Secret/private key. */
|
||||
unsigned char* sk;
|
||||
/* Length of secret key. */
|
||||
word32 sk_len;
|
||||
/* Callback to write/update key. */
|
||||
wc_xmss_write_private_key_cb write_private_key;
|
||||
/* Callback to read key. */
|
||||
wc_xmss_read_private_key_cb read_private_key;
|
||||
/* Context arg passed to callbacks. */
|
||||
void* context;
|
||||
#endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY */
|
||||
/* State of key. */
|
||||
enum wc_XmssState state;
|
||||
};
|
||||
|
||||
typedef struct XmssState {
|
||||
const XmssParams* params;
|
||||
|
||||
/* Digest is assumed to be at the end. */
|
||||
union {
|
||||
#ifdef WC_XMSS_SHA256
|
||||
wc_Sha256 sha256;
|
||||
#endif
|
||||
#ifdef WC_XMSS_SHA512
|
||||
wc_Sha512 sha512;
|
||||
#endif
|
||||
#if defined(WC_XMSS_SHAKE128) || defined(WC_XMSS_SHAKE256)
|
||||
wc_Shake shake;
|
||||
#endif
|
||||
} digest;
|
||||
#if !defined(WOLFSSL_WC_XMSS_SMALL) && defined(WC_XMSS_SHA256) && \
|
||||
!defined(WC_XMSS_FULL_HASH)
|
||||
ALIGN16 word32 dgst_state[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
|
||||
#endif
|
||||
ALIGN16 byte prf_buf[WC_XMSS_HASH_PRF_MAX_DATA_LEN];
|
||||
ALIGN16 byte buf[WC_XMSS_HASH_MAX_DATA_LEN];
|
||||
ALIGN16 byte pk[WC_XMSS_MAX_WOTS_SIG_LEN];
|
||||
#ifndef WOLFSSL_XMSS_VERIFY_ONLY
|
||||
ALIGN16 byte stack[WC_XMSS_MAX_STACK_LEN];
|
||||
#else
|
||||
ALIGN16 byte stack[WC_XMSS_ADDR_LEN];
|
||||
#endif
|
||||
byte encMsg[WC_XMSS_MAX_WOTS_LEN];
|
||||
HashAddress addr;
|
||||
|
||||
int ret;
|
||||
} XmssState;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WOLFSSL_LOCAL int wc_xmssmt_keygen(XmssState *state, const unsigned char* seed,
|
||||
unsigned char *sk, unsigned char *pk);
|
||||
WOLFSSL_LOCAL int wc_xmss_keygen(XmssState *state, const unsigned char* seed,
|
||||
unsigned char *sk, unsigned char *pk);
|
||||
|
||||
WOLFSSL_LOCAL int wc_xmssmt_sign(XmssState *state, const unsigned char *m,
|
||||
word32 mlen, unsigned char *sk, unsigned char *sm);
|
||||
WOLFSSL_LOCAL int wc_xmss_sign(XmssState *state, const unsigned char *m,
|
||||
word32 mlen, unsigned char *sk, unsigned char *sm);
|
||||
|
||||
WOLFSSL_LOCAL int wc_xmss_sigsleft(const XmssParams* params, unsigned char* sk);
|
||||
|
||||
WOLFSSL_LOCAL int wc_xmssmt_verify(XmssState *state, const unsigned char *m,
|
||||
word32 mlen, const unsigned char *sm, const unsigned char *pk);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_HAVE_XMSS */
|
||||
#endif /* WC_XMSS_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user