|
@@ -154,6 +154,12 @@
|
|
|
#include <wolfssl/wolfcrypt/ext_kyber.h>
|
|
|
#endif
|
|
|
#endif
|
|
|
+#ifdef WOLFSSL_HAVE_LMS
|
|
|
+ #include <wolfssl/wolfcrypt/lms.h>
|
|
|
+#ifdef HAVE_LIBLMS
|
|
|
+ #include <wolfssl/wolfcrypt/ext_lms.h>
|
|
|
+#endif
|
|
|
+#endif
|
|
|
#ifdef WOLFCRYPT_HAVE_ECCSI
|
|
|
#include <wolfssl/wolfcrypt/eccsi.h>
|
|
|
#endif
|
|
@@ -565,6 +571,9 @@
|
|
|
#define BENCH_SPHINCS_SMALL_LEVEL3_SIGN 0x00000010
|
|
|
#define BENCH_SPHINCS_SMALL_LEVEL5_SIGN 0x00000020
|
|
|
|
|
|
+/* Post-Quantum Stateful Hash-Based sig algorithms. */
|
|
|
+#define BENCH_LMS_HSS 0x00000001
|
|
|
+
|
|
|
/* Other */
|
|
|
#define BENCH_RNG 0x00000001
|
|
|
#define BENCH_SCRYPT 0x00000002
|
|
@@ -603,6 +612,8 @@ static word32 bench_pq_asym_algs = 0;
|
|
|
static word32 bench_pq_asym_algs2 = 0;
|
|
|
/* Other cryptographic algorithms to benchmark. */
|
|
|
static word32 bench_other_algs = 0;
|
|
|
+/* Post-Quantum Stateful Hash-Based sig algorithms to benchmark. */
|
|
|
+static word32 bench_pq_hash_sig_algs = 0;
|
|
|
|
|
|
#if !defined(WOLFSSL_BENCHMARK_ALL) && !defined(NO_MAIN_DRIVER)
|
|
|
|
|
@@ -856,6 +867,21 @@ static const bench_alg bench_other_opt[] = {
|
|
|
|
|
|
#endif /* !WOLFSSL_BENCHMARK_ALL && !NO_MAIN_DRIVER */
|
|
|
|
|
|
+#if defined(WOLFSSL_HAVE_LMS)
|
|
|
+typedef struct bench_pq_hash_sig_alg {
|
|
|
+ /* Command line option string. */
|
|
|
+ const char* str;
|
|
|
+ /* Bit values to set. */
|
|
|
+ word32 val;
|
|
|
+} bench_pq_hash_sig_alg;
|
|
|
+
|
|
|
+static const bench_pq_hash_sig_alg bench_pq_hash_sig_opt[] = {
|
|
|
+ { "-pq_hash_sig", 0xffffffff},
|
|
|
+ { "-lms_hss", BENCH_LMS_HSS},
|
|
|
+ { NULL, 0}
|
|
|
+};
|
|
|
+#endif /* if defined(WOLFSSL_HAVE_LMS) */
|
|
|
+
|
|
|
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
|
|
|
/* The post-quantum-specific mapping of command line option to bit values and
|
|
|
* OQS name. */
|
|
@@ -1592,6 +1618,7 @@ static void benchmark_static_init(int force)
|
|
|
bench_asym_algs = 0;
|
|
|
bench_pq_asym_algs = 0;
|
|
|
bench_other_algs = 0;
|
|
|
+ bench_pq_hash_sig_algs = 0;
|
|
|
csv_format = 0;
|
|
|
}
|
|
|
}
|
|
@@ -2798,6 +2825,12 @@ static void* benchmarks_do(void* args)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+#ifdef WOLFSSL_HAVE_LMS
|
|
|
+ if (bench_all || (bench_pq_hash_sig_algs & BENCH_LMS_HSS)) {
|
|
|
+ bench_lms();
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
#ifdef HAVE_ECC
|
|
|
if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY) ||
|
|
|
(bench_asym_algs & BENCH_ECC) ||
|
|
@@ -7624,6 +7657,375 @@ void bench_kyber(int type)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+#ifdef WOLFSSL_HAVE_LMS
|
|
|
+/* WC_LMS_PARM_L2_H10_W2
|
|
|
+ * signature length: 9300 */
|
|
|
+static const byte lms_priv_L2_H10_W2[64] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x62,0x62,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
|
+ 0xC7,0x74,0x25,0x5B,0x2C,0xE8,0xDA,0x53,
|
|
|
+ 0xF0,0x7C,0x04,0x3F,0x64,0x2D,0x26,0x2C,
|
|
|
+ 0x46,0x1D,0xC8,0x90,0x77,0x59,0xD6,0xC0,
|
|
|
+ 0x56,0x46,0x7D,0x97,0x64,0xF2,0xA3,0xA1,
|
|
|
+ 0xF8,0xD0,0x3B,0x5F,0xAC,0x40,0xB9,0x9E,
|
|
|
+ 0x83,0x67,0xBF,0x92,0x8D,0xFE,0x45,0x79
|
|
|
+};
|
|
|
+
|
|
|
+static const byte lms_pub_L2_H10_W2[60] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,
|
|
|
+ 0x00,0x00,0x00,0x02,0xF8,0xD0,0x3B,0x5F,
|
|
|
+ 0xAC,0x40,0xB9,0x9E,0x83,0x67,0xBF,0x92,
|
|
|
+ 0x8D,0xFE,0x45,0x79,0x41,0xBC,0x2A,0x3B,
|
|
|
+ 0x9F,0xC0,0x11,0x12,0x93,0xF0,0x5A,0xA5,
|
|
|
+ 0xC1,0x88,0x29,0x79,0x6C,0x3E,0x0A,0x0F,
|
|
|
+ 0xEC,0x3B,0x3E,0xE4,0x38,0xD3,0xD2,0x34,
|
|
|
+ 0x7F,0xC8,0x91,0xB0
|
|
|
+};
|
|
|
+
|
|
|
+/* WC_LMS_PARM_L2_H10_W4
|
|
|
+ * signature length: 5076 */
|
|
|
+static const byte lms_priv_L2_H10_W4[64] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x63,0x63,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
|
+ 0xAE,0x28,0x87,0x19,0x4F,0x4B,0x68,0x61,
|
|
|
+ 0x93,0x9A,0xC7,0x0E,0x33,0xB8,0xCE,0x96,
|
|
|
+ 0x66,0x0D,0xC7,0xB1,0xFA,0x94,0x80,0xA2,
|
|
|
+ 0x28,0x9B,0xCF,0xE2,0x08,0xB5,0x25,0xAC,
|
|
|
+ 0xFB,0xB8,0x65,0x5E,0xD1,0xCC,0x31,0xDA,
|
|
|
+ 0x2E,0x49,0x3A,0xEE,0xAF,0x63,0x70,0x5E
|
|
|
+};
|
|
|
+
|
|
|
+static const byte lms_pub_L2_H10_W4[60] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x06,
|
|
|
+ 0x00,0x00,0x00,0x03,0xFB,0xB8,0x65,0x5E,
|
|
|
+ 0xD1,0xCC,0x31,0xDA,0x2E,0x49,0x3A,0xEE,
|
|
|
+ 0xAF,0x63,0x70,0x5E,0xA2,0xD5,0xB6,0x15,
|
|
|
+ 0x33,0x8C,0x9B,0xE9,0xE1,0x91,0x40,0x1A,
|
|
|
+ 0x12,0xE0,0xD7,0xBD,0xE4,0xE0,0x76,0xF5,
|
|
|
+ 0x04,0x90,0x76,0xA5,0x9A,0xA7,0x4E,0xFE,
|
|
|
+ 0x6B,0x9A,0xD3,0x14
|
|
|
+};
|
|
|
+
|
|
|
+/* WC_LMS_PARM_L3_H5_W4
|
|
|
+ * signature length: 7160 */
|
|
|
+static const byte lms_priv_L3_H5_W4[64] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x53,0x53,0x53,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
|
+ 0x38,0xD1,0xBE,0x68,0xD1,0x93,0xE1,0x14,
|
|
|
+ 0x6C,0x8B,0xED,0xE2,0x25,0x88,0xED,0xAC,
|
|
|
+ 0x57,0xBD,0x87,0x9F,0x54,0xF3,0x58,0xD9,
|
|
|
+ 0x4D,0xF5,0x6A,0xBD,0x71,0x99,0x6A,0x28,
|
|
|
+ 0x2F,0xE1,0xFC,0xD1,0xD1,0x0C,0x7C,0xF8,
|
|
|
+ 0xB4,0xDC,0xDF,0x7F,0x14,0x1A,0x7B,0x50
|
|
|
+};
|
|
|
+
|
|
|
+static const byte lms_pub_L3_H5_W4[60] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x05,
|
|
|
+ 0x00,0x00,0x00,0x03,0x2F,0xE1,0xFC,0xD1,
|
|
|
+ 0xD1,0x0C,0x7C,0xF8,0xB4,0xDC,0xDF,0x7F,
|
|
|
+ 0x14,0x1A,0x7B,0x50,0x8E,0x3A,0xD4,0x05,
|
|
|
+ 0x0C,0x95,0x59,0xA0,0xCA,0x7A,0xD8,0xD6,
|
|
|
+ 0x5D,0xBD,0x42,0xBB,0xD5,0x82,0xB8,0x9C,
|
|
|
+ 0x52,0x37,0xB7,0x45,0x03,0xC2,0x06,0xCE,
|
|
|
+ 0xAB,0x4B,0x51,0x39
|
|
|
+};
|
|
|
+
|
|
|
+/* WC_LMS_PARM_L3_H5_W8
|
|
|
+ * signature length: 3992 */
|
|
|
+static const byte lms_priv_L3_H5_W8[64] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x54,0x54,0x54,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
|
+ 0xA5,0x46,0x97,0x0C,0xA1,0x3C,0xEA,0x17,
|
|
|
+ 0x5C,0x9D,0x59,0xF4,0x0E,0x27,0x37,0xF3,
|
|
|
+ 0x6A,0x1C,0xF7,0x29,0x4A,0xCC,0xCD,0x7B,
|
|
|
+ 0x4F,0xE7,0x37,0x6E,0xEF,0xC1,0xBD,0xBD,
|
|
|
+ 0x04,0x5D,0x8E,0xDD,0xAA,0x47,0xCC,0xE6,
|
|
|
+ 0xCE,0x78,0x46,0x20,0x41,0x87,0xE0,0x85
|
|
|
+};
|
|
|
+
|
|
|
+static const byte lms_pub_L3_H5_W8[60] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x05,
|
|
|
+ 0x00,0x00,0x00,0x04,0x04,0x5D,0x8E,0xDD,
|
|
|
+ 0xAA,0x47,0xCC,0xE6,0xCE,0x78,0x46,0x20,
|
|
|
+ 0x41,0x87,0xE0,0x85,0x0D,0x2C,0x46,0xB9,
|
|
|
+ 0x39,0x8C,0xA3,0x92,0x4F,0xCE,0x50,0x96,
|
|
|
+ 0x90,0x9C,0xF3,0x36,0x2E,0x09,0x15,0x3B,
|
|
|
+ 0x4B,0x34,0x17,0xE7,0xE2,0x55,0xFC,0x5B,
|
|
|
+ 0x83,0xAB,0x43,0xAF
|
|
|
+};
|
|
|
+
|
|
|
+/* WC_LMS_PARM_L3_H10_W4
|
|
|
+ * signature length: 7640 */
|
|
|
+static const byte lms_priv_L3_H10_W4[64] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x63,0x63,0x63,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
|
+ 0xDF,0x98,0xAB,0xEC,0xFE,0x13,0x9F,0xF8,
|
|
|
+ 0xD7,0x2B,0x4F,0x4C,0x79,0x34,0xB8,0x89,
|
|
|
+ 0x24,0x6B,0x26,0x7D,0x7A,0x2E,0xA2,0xCB,
|
|
|
+ 0x82,0x75,0x4E,0x96,0x54,0x49,0xED,0xA0,
|
|
|
+ 0xAF,0xC7,0xA5,0xEE,0x8A,0xA2,0x83,0x99,
|
|
|
+ 0x4B,0x18,0x59,0x2B,0x66,0xC0,0x32,0xDB
|
|
|
+};
|
|
|
+
|
|
|
+static const byte lms_pub_L3_H10_W4[60] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,
|
|
|
+ 0x00,0x00,0x00,0x03,0xAF,0xC7,0xA5,0xEE,
|
|
|
+ 0x8A,0xA2,0x83,0x99,0x4B,0x18,0x59,0x2B,
|
|
|
+ 0x66,0xC0,0x32,0xDB,0xC4,0x18,0xEB,0x11,
|
|
|
+ 0x17,0x7D,0xAA,0x93,0xFD,0xA0,0x70,0x4D,
|
|
|
+ 0x68,0x4B,0x63,0x8F,0xC2,0xE7,0xCA,0x34,
|
|
|
+ 0x14,0x31,0x0D,0xAA,0x18,0xBF,0x9B,0x32,
|
|
|
+ 0x8D,0x78,0xD5,0xA8
|
|
|
+};
|
|
|
+
|
|
|
+/* WC_LMS_PARM_L4_H5_W8
|
|
|
+ * signature length: 5340 */
|
|
|
+static const byte lms_priv_L4_H5_W8[64] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
|
+ 0x54,0x54,0x54,0x54,0xFF,0xFF,0xFF,0xFF,
|
|
|
+ 0x46,0x8F,0x2A,0x4A,0x14,0x26,0xF0,0x89,
|
|
|
+ 0xFE,0xED,0x66,0x0F,0x73,0x69,0xB1,0x4C,
|
|
|
+ 0x47,0xA1,0x35,0x9F,0x7B,0xBA,0x08,0x03,
|
|
|
+ 0xEE,0xA2,0xEB,0xAD,0xB4,0x82,0x52,0x1F,
|
|
|
+ 0xFD,0x9B,0x22,0x82,0x42,0x1A,0x96,0x1E,
|
|
|
+ 0xE4,0xA1,0x9C,0x33,0xED,0xE6,0x9F,0xAB
|
|
|
+};
|
|
|
+
|
|
|
+static const byte lms_pub_L4_H5_W8[60] =
|
|
|
+{
|
|
|
+ 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,
|
|
|
+ 0x00,0x00,0x00,0x04,0xFD,0x9B,0x22,0x82,
|
|
|
+ 0x42,0x1A,0x96,0x1E,0xE4,0xA1,0x9C,0x33,
|
|
|
+ 0xED,0xE6,0x9F,0xAB,0x6B,0x47,0x05,0x5B,
|
|
|
+ 0xA7,0xAD,0xF6,0x88,0xA5,0x4F,0xCD,0xF1,
|
|
|
+ 0xDA,0x29,0x67,0xC3,0x7F,0x2C,0x11,0xFE,
|
|
|
+ 0x85,0x1A,0x7A,0xD8,0xD5,0x46,0x74,0x3B,
|
|
|
+ 0x74,0x24,0x12,0xC8
|
|
|
+};
|
|
|
+
|
|
|
+static int lms_write_key_mem(const byte * priv, word32 privSz, void *context)
|
|
|
+{
|
|
|
+ /* WARNING: THIS IS AN INSECURE WRITE CALLBACK THAT SHOULD ONLY
|
|
|
+ * BE USED FOR TESTING PURPOSES! Production applications should
|
|
|
+ * write only to non-volatile storage. */
|
|
|
+ XMEMCPY(context, priv, privSz);
|
|
|
+ return WC_LMS_RC_SAVED_TO_NV_MEMORY;
|
|
|
+}
|
|
|
+
|
|
|
+static int lms_read_key_mem(byte * priv, word32 privSz, void *context)
|
|
|
+{
|
|
|
+ /* WARNING: THIS IS AN INSECURE READ CALLBACK THAT SHOULD ONLY
|
|
|
+ * BE USED FOR TESTING PURPOSES! */
|
|
|
+ XMEMCPY(priv, context, privSz);
|
|
|
+ return WC_LMS_RC_READ_TO_MEMORY;
|
|
|
+}
|
|
|
+
|
|
|
+static void bench_lms_sign_verify(enum wc_LmsParm parm)
|
|
|
+{
|
|
|
+ LmsKey key;
|
|
|
+ int ret = 0;
|
|
|
+ const char * msg = TEST_STRING;
|
|
|
+ word32 msgSz = TEST_STRING_SZ;
|
|
|
+ byte * sig = NULL;
|
|
|
+ word32 sigSz = 0;
|
|
|
+ word32 privLen = 0;
|
|
|
+ int loaded = 0;
|
|
|
+ int times = 0;
|
|
|
+ int count = 0;
|
|
|
+ double start = 0.0F;
|
|
|
+ byte priv[HSS_MAX_PRIVATE_KEY_LEN];
|
|
|
+ const char * str = wc_LmsKey_ParmToStr(parm);
|
|
|
+
|
|
|
+ ret = wc_LmsKey_Init(&key, NULL, INVALID_DEVID);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_Init failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = wc_LmsKey_SetLmsParm(&key, parm);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_SetLmsParm failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (parm) {
|
|
|
+ case WC_LMS_PARM_L2_H10_W2:
|
|
|
+ XMEMCPY(priv, lms_priv_L2_H10_W2, sizeof(lms_priv_L2_H10_W2));
|
|
|
+ XMEMCPY(key.pub, lms_pub_L2_H10_W2, sizeof(lms_pub_L2_H10_W2));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case WC_LMS_PARM_L2_H10_W4:
|
|
|
+ XMEMCPY(priv, lms_priv_L2_H10_W4, sizeof(lms_priv_L2_H10_W4));
|
|
|
+ XMEMCPY(key.pub, lms_pub_L2_H10_W4, sizeof(lms_pub_L2_H10_W4));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case WC_LMS_PARM_L3_H5_W4:
|
|
|
+ XMEMCPY(priv, lms_priv_L3_H5_W4, sizeof(lms_priv_L3_H5_W4));
|
|
|
+ XMEMCPY(key.pub, lms_pub_L3_H5_W4, sizeof(lms_pub_L3_H5_W4));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case WC_LMS_PARM_L3_H5_W8:
|
|
|
+ XMEMCPY(priv, lms_priv_L3_H5_W8, sizeof(lms_priv_L3_H5_W8));
|
|
|
+ XMEMCPY(key.pub, lms_pub_L3_H5_W8, sizeof(lms_pub_L3_H5_W8));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case WC_LMS_PARM_L3_H10_W4:
|
|
|
+ XMEMCPY(priv, lms_priv_L3_H10_W4, sizeof(lms_priv_L3_H10_W4));
|
|
|
+ XMEMCPY(key.pub, lms_pub_L3_H10_W4, sizeof(lms_pub_L3_H10_W4));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case WC_LMS_PARM_L4_H5_W8:
|
|
|
+ XMEMCPY(priv, lms_priv_L4_H5_W8, sizeof(lms_priv_L4_H5_W8));
|
|
|
+ XMEMCPY(key.pub, lms_pub_L4_H5_W8, sizeof(lms_pub_L4_H5_W8));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case WC_LMS_PARM_NONE:
|
|
|
+ case WC_LMS_PARM_L1_H15_W2:
|
|
|
+ case WC_LMS_PARM_L1_H15_W4:
|
|
|
+ case WC_LMS_PARM_L2_H10_W8:
|
|
|
+ case WC_LMS_PARM_L3_H5_W2:
|
|
|
+ printf("bench_lms_sign_verify: unsupported benchmark option: %d\n",
|
|
|
+ parm);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = wc_LmsKey_SetWriteCb(&key, lms_write_key_mem);
|
|
|
+ if (ret) {
|
|
|
+ fprintf(stderr, "error: wc_LmsKey_SetWriteCb failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = wc_LmsKey_SetReadCb(&key, lms_read_key_mem);
|
|
|
+ if (ret) {
|
|
|
+ fprintf(stderr, "error: wc_LmsKey_SetReadCb failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = wc_LmsKey_SetContext(&key, (void *) priv);
|
|
|
+ if (ret) {
|
|
|
+ fprintf(stderr, "error: wc_LmsKey_SetContext failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Even with saved priv/pub keys, we must still reload the private
|
|
|
+ * key before using it. Reloading the private key is the bottleneck
|
|
|
+ * for larger heights. Only print load time in debug builds. */
|
|
|
+#if defined(DEBUG_WOLFSSL)
|
|
|
+ bench_stats_start(&count, &start);
|
|
|
+#endif /* if defined DEBUG_WOLFSSL*/
|
|
|
+
|
|
|
+ ret = wc_LmsKey_Reload(&key);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_Reload failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ count +=1;
|
|
|
+
|
|
|
+ ret = wc_LmsKey_GetSigLen(&key, &sigSz);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_GetSigLen failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = wc_LmsKey_GetPrivLen(&key, &privLen);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_GetPrivLen failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+#if defined(DEBUG_WOLFSSL)
|
|
|
+ bench_stats_check(start);
|
|
|
+ bench_stats_asym_finish(str, (int)privLen, "load", 0,
|
|
|
+ count, start, ret);
|
|
|
+#endif /* if defined DEBUG_WOLFSSL*/
|
|
|
+
|
|
|
+ loaded = 1;
|
|
|
+
|
|
|
+ sig = XMALLOC(sigSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
|
+ if (sig == NULL) {
|
|
|
+ printf("bench_lms_sign_verify malloc failed\n");
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+
|
|
|
+ count = 0;
|
|
|
+ bench_stats_start(&count, &start);
|
|
|
+
|
|
|
+ do {
|
|
|
+ /* LMS is stateful. Async queuing not practical. */
|
|
|
+ for (times = 0; times < ntimes; ++times) {
|
|
|
+
|
|
|
+ ret = wc_LmsKey_Sign(&key, sig, &sigSz, (byte *) msg, msgSz);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_Sign failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ count += times;
|
|
|
+ } while (bench_stats_check(start));
|
|
|
+
|
|
|
+ bench_stats_asym_finish(str, (int)sigSz, "sign", 0,
|
|
|
+ count, start, ret);
|
|
|
+
|
|
|
+ count = 0;
|
|
|
+ bench_stats_start(&count, &start);
|
|
|
+
|
|
|
+ do {
|
|
|
+ /* LMS is stateful. Async queuing not practical. */
|
|
|
+ for (times = 0; times < ntimes; ++times) {
|
|
|
+ ret = wc_LmsKey_Verify(&key, sig, sigSz, (byte *) msg, msgSz);
|
|
|
+ if (ret) {
|
|
|
+ printf("wc_LmsKey_Verify failed: %d\n", ret);
|
|
|
+ goto exit_lms_sign_verify;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ count += times;
|
|
|
+ } while (bench_stats_check(start));
|
|
|
+
|
|
|
+exit_lms_sign_verify:
|
|
|
+ bench_stats_asym_finish(str, (int)sigSz, "verify", 0,
|
|
|
+ count, start, ret);
|
|
|
+
|
|
|
+
|
|
|
+ if (loaded) {
|
|
|
+ wc_LmsKey_Free(&key);
|
|
|
+ loaded = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sig != NULL) {
|
|
|
+ XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
|
|
+ sig = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+void bench_lms(void)
|
|
|
+{
|
|
|
+ bench_lms_sign_verify(WC_LMS_PARM_L2_H10_W2);
|
|
|
+ bench_lms_sign_verify(WC_LMS_PARM_L2_H10_W4);
|
|
|
+ bench_lms_sign_verify(WC_LMS_PARM_L3_H5_W4);
|
|
|
+ bench_lms_sign_verify(WC_LMS_PARM_L3_H5_W8);
|
|
|
+ bench_lms_sign_verify(WC_LMS_PARM_L3_H10_W4);
|
|
|
+ bench_lms_sign_verify(WC_LMS_PARM_L4_H5_W8);
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* ifdef WOLFSSL_HAVE_LMS */
|
|
|
+
|
|
|
#ifdef HAVE_ECC
|
|
|
|
|
|
/* Maximum ECC name plus null terminator:
|
|
@@ -9952,6 +10354,10 @@ static void Usage(void)
|
|
|
print_alg(bench_pq_asym_opt2[i].str, &line);
|
|
|
#endif /* HAVE_LIBOQS */
|
|
|
#endif /* HAVE_PQC */
|
|
|
+#if defined(WOLFSSL_HAVE_LMS)
|
|
|
+ for (i=0; bench_pq_hash_sig_opt[i].str != NULL; i++)
|
|
|
+ print_alg(bench_pq_hash_sig_opt[i].str, &line);
|
|
|
+#endif /* if defined(WOLFSSL_HAVE_LMS) */
|
|
|
printf("\n");
|
|
|
#endif /* !WOLFSSL_BENCHMARK_ALL */
|
|
|
e++;
|
|
@@ -10211,6 +10617,17 @@ int wolfcrypt_benchmark_main(int argc, char** argv)
|
|
|
optMatched = 1;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ #if defined(WOLFSSL_HAVE_LMS)
|
|
|
+ /* post-quantum stateful hash-based signatures */
|
|
|
+ for (i=0; !optMatched && bench_pq_hash_sig_opt[i].str != NULL; i++) {
|
|
|
+ if (string_matches(argv[1], bench_pq_hash_sig_opt[i].str)) {
|
|
|
+ bench_pq_hash_sig_algs |= bench_pq_hash_sig_opt[i].val;
|
|
|
+ bench_all = 0;
|
|
|
+ optMatched = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endif /* if defined(WOLFSSL_HAVE_LMS) */
|
|
|
#endif
|
|
|
if (!optMatched) {
|
|
|
printf("Option not recognized: %s\n", argv[1]);
|