Merge pull request #7500 from SparkiDev/lms_xmss_move_wolfcrypt

LMS, XMSS: move code into wolfCrypt
This commit is contained in:
Daniel Pouzzner
2024-05-07 01:12:18 -04:00
committed by GitHub
7 changed files with 10887 additions and 55 deletions
+26 -42
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1643 -1
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+448 -1
View File
@@ -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
View File
@@ -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 */