diff --git a/INSTALL b/INSTALL
index 79d40e3a5..282feceb5 100644
--- a/INSTALL
+++ b/INSTALL
@@ -138,14 +138,19 @@
 
 15. Building with liboqs for TLS 1.3 [EXPERIMENTAL]
     In order be able to use liboqs, you must have it built and installed on your
-    system. We support the 0.7.0 release of liboqs. You can download it from
-    the following link:
+    system. We support liboqs at a specific git commit.
 
-    https://github.com/open-quantum-safe/liboqs/archive/refs/tags/0.7.0.tar.gz
+    NOTE: Even if you have already installed liboqs, you need to follow these
+          steps to install liboqs again as we support sphincs variants that are
+          disabled by default in OQS's fork of OpenSSL.
 
-    Once unpacked, this would be sufficient:
+    Here are instructions for obtaining and building liboqs:
 
-    $ cd liboqs-0.7.0
+    $ mkdir ~/oqs
+    $ cd ~/oqs
+    $ git clone --single-branch https://github.com/open-quantum-safe/liboqs.git
+    $ cd liboqs/
+    $ git checkout af76ca3b1f2fbc1f4f0967595f3bb07692fb3d82
     $ mkdir build
     $ cd build
     $ cmake -DOQS_USE_OPENSSL=0 ..
@@ -176,32 +181,24 @@
     Using Post-Quantum KEM: P521_KYBER_LEVEL5
     ```
 
-    For authentication, you can generate a certificate chain using the Open
-    Quantum Safe project's fork of OpenSSL. We support certificates and keys
-    generated by the 2021-08 snapshot of the OQS-OpenSSL_1_1_1-stable branch
-    of the fork. You can download it from the following link:
+    For authentication, you can generate a certificate chain using a patch on
+    top of the Open Quantum Safe project's fork of OpenSSL. We support
+    certificates and keys generated by the patched version which is maintained
+    in our OSP repo.
 
-    https://github.com/open-quantum-safe/openssl/archive/refs/tags/OQS-OpenSSL_1_1_1-stable-snapshot-2021-08.tar.gz
+    Instructions for obtaining and building our patched version of OQS's fork of
+    OpenSSL can be found at:
 
-    Once unpacked, this would be sufficient for building it:
+    https://github.com/wolfSSL/osp/tree/master/oqs/README.md
 
-    $ cd openssl-OQS-OpenSSL_1_1_1-stable-snapshot-2021-08/
-    $ ./config no-shared
-    $ make all
-
-    Note that installation is NOT required.
-
-    There is a script for generating a Falcon NIST Level 1 and NIST Level 5
-    certificate chain which can be found in the wolfssl-examples github repo at
-    pq/generate_falcon_chains.sh. Please find detailed instructions on how to
-    generate and verify the keys and certificates in pq/README.md. As a quick-
-    start, simply copy generate_falcon_chains.sh into the
-    openssl-OQS-OpenSSL_1_1_1-stable-snapshot-2021-08 directory and execute the
-    script.
+    There are scripts for generating FALCON, Dilithium and SPHINCS+ certificate
+    chains which can be found in the same directory as the `README.md` file in
+    the `osp` github repo. Please find instructions on how to generate the keys
+    and certificates in the `README.md` file.
 
     Once the certificates and keys are generated, copy them from the
-    openssl-OQS-OpenSSL_1_1_1-stable-snapshot-2021-08/ directory to the certs
-    directory of wolfssl. Now you can run the server and client like this:
+    to the certs directory of wolfssl. Now you can run the server and client
+    like this:
 
     $ examples/server/server -v 4 -l TLS_AES_256_GCM_SHA384 \
       -A certs/falcon_level5_root_cert.pem \
@@ -218,13 +215,18 @@
     Congratulations! You have just achieved a fully quantum-safe TLS 1.3
     connection!
 
-    The following NIST Competition Round 3 Finalist algorithms are supported:
+    The following NIST Competition winning algorithms are supported:
     - CRYSTALS-KYBER (KEM)
+    - Dilithium (signature scheme)
+    - FALCON (signature scheme)
+    - SPHINCS+ (signature scheme)
+
+    The following NIST Competition Round 3 finalist algorithms are supported,
+    but are deprecated and will be removed soon:
     - SABER (KEM)
     - NTRU (KEM)
-    - FALCON (signature scheme)
 
-    Links to more information about these algorithms can be found here:
+    Links to more information about all of these algorithms can be found here:
 
     https://csrc.nist.gov/projects/post-quantum-cryptography/round-3-submissions
 
diff --git a/certs/include.am b/certs/include.am
index f81c2c36d..be19b392e 100644
--- a/certs/include.am
+++ b/certs/include.am
@@ -130,4 +130,5 @@ include certs/intermediate/include.am
 include certs/falcon/include.am
 include certs/rsapss/include.am
 include certs/dilithium/include.am
+include certs/sphincs/include.am
 
diff --git a/certs/sphincs/bench_sphincs_fast_level1_key.der b/certs/sphincs/bench_sphincs_fast_level1_key.der
new file mode 100644
index 000000000..fa3dd5b23
Binary files /dev/null and b/certs/sphincs/bench_sphincs_fast_level1_key.der differ
diff --git a/certs/sphincs/bench_sphincs_fast_level3_key.der b/certs/sphincs/bench_sphincs_fast_level3_key.der
new file mode 100644
index 000000000..4aac53289
Binary files /dev/null and b/certs/sphincs/bench_sphincs_fast_level3_key.der differ
diff --git a/certs/sphincs/bench_sphincs_fast_level5_key.der b/certs/sphincs/bench_sphincs_fast_level5_key.der
new file mode 100644
index 000000000..8fa2a3241
Binary files /dev/null and b/certs/sphincs/bench_sphincs_fast_level5_key.der differ
diff --git a/certs/sphincs/bench_sphincs_small_level1_key.der b/certs/sphincs/bench_sphincs_small_level1_key.der
new file mode 100644
index 000000000..72f750c58
Binary files /dev/null and b/certs/sphincs/bench_sphincs_small_level1_key.der differ
diff --git a/certs/sphincs/bench_sphincs_small_level3_key.der b/certs/sphincs/bench_sphincs_small_level3_key.der
new file mode 100644
index 000000000..1b3d32561
Binary files /dev/null and b/certs/sphincs/bench_sphincs_small_level3_key.der differ
diff --git a/certs/sphincs/bench_sphincs_small_level5_key.der b/certs/sphincs/bench_sphincs_small_level5_key.der
new file mode 100644
index 000000000..ba78786af
Binary files /dev/null and b/certs/sphincs/bench_sphincs_small_level5_key.der differ
diff --git a/certs/sphincs/include.am b/certs/sphincs/include.am
new file mode 100644
index 000000000..2d44e66b7
--- /dev/null
+++ b/certs/sphincs/include.am
@@ -0,0 +1,11 @@
+# vim:ft=automake
+# All paths should be given relative to the root
+#
+
+EXTRA_DIST += \
+         certs/sphincs/bench_sphincs_fast_level1_key.der \
+         certs/sphincs/bench_sphincs_fast_level3_key.der \
+         certs/sphincs/bench_sphincs_fast_level5_key.der \
+         certs/sphincs/bench_sphincs_small_level1_key.der \
+         certs/sphincs/bench_sphincs_small_level3_key.der \
+         certs/sphincs/bench_sphincs_small_level5_key.der
diff --git a/gencertbuf.pl b/gencertbuf.pl
index 59c2c6253..27bc80cfb 100755
--- a/gencertbuf.pl
+++ b/gencertbuf.pl
@@ -116,6 +116,18 @@ my @fileList_dilithium = (
         ["certs/dilithium/bench_dilithium_aes_level5_key.der", "bench_dilithium_aes_level5_key" ],
         );
 
+#Sphincs+ Post-Quantum Keys
+#Used with HAVE_PQC
+my @fileList_sphincs = (
+        ["certs/sphincs/bench_sphincs_fast_level1_key.der", "bench_sphincs_fast_level1_key" ],
+        ["certs/sphincs/bench_sphincs_fast_level3_key.der", "bench_sphincs_fast_level3_key" ],
+        ["certs/sphincs/bench_sphincs_fast_level5_key.der", "bench_sphincs_fast_level5_key" ],
+        ["certs/sphincs/bench_sphincs_small_level1_key.der", "bench_sphincs_small_level1_key" ],
+        ["certs/sphincs/bench_sphincs_small_level3_key.der", "bench_sphincs_small_level3_key" ],
+        ["certs/sphincs/bench_sphincs_small_level5_key.der", "bench_sphincs_small_level5_key" ],
+        );
+
+
 # ----------------------------------------------------------------------------
 
 my $num_ecc = @fileList_ecc;
@@ -126,6 +138,7 @@ my $num_3072 = @fileList_3072;
 my $num_4096 = @fileList_4096;
 my $num_falcon = @fileList_falcon;
 my $num_dilithium = @fileList_dilithium;
+my $num_sphincs = @fileList_sphincs;
 
 # open our output file, "+>" creates and/or truncates
 open OUT_FILE, "+>", $outputFile  or die $!;
@@ -206,7 +219,7 @@ for (my $i = 0; $i < $num_4096; $i++) {
 print OUT_FILE "#endif /* USE_CERT_BUFFERS_4096 */\n\n";
 
 # convert and print falcon keys
-print OUT_FILE "#ifdef HAVE_PQC && HAVE_FALCON\n\n";
+print OUT_FILE "#if defined(HAVE_PQC) && defined(HAVE_FALCON)\n\n";
 for (my $i = 0; $i < $num_falcon; $i++) {
 
     my $fname = $fileList_falcon[$i][0];
@@ -223,7 +236,7 @@ for (my $i = 0; $i < $num_falcon; $i++) {
 print OUT_FILE "#endif /* HAVE_PQC && HAVE_FALCON */\n\n";
 
 # convert and print dilithium keys
-print OUT_FILE "#ifdef HAVE_PQC && HAVE_DILITHIUM\n\n";
+print OUT_FILE "#if defined (HAVE_PQC) && defined(HAVE_DILITHIUM)\n\n";
 for (my $i = 0; $i < $num_dilithium; $i++) {
 
     my $fname = $fileList_dilithium[$i][0];
@@ -239,6 +252,23 @@ for (my $i = 0; $i < $num_dilithium; $i++) {
 
 print OUT_FILE "#endif /* HAVE_PQC && HAVE_DILITHIUM */\n\n";
 
+# convert and print sphincs keys
+print OUT_FILE "#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)\n\n";
+for (my $i = 0; $i < $num_sphincs; $i++) {
+
+    my $fname = $fileList_sphincs[$i][0];
+    my $sname = $fileList_sphincs[$i][1];
+
+    print OUT_FILE "/* $fname */\n";
+    print OUT_FILE "static const unsigned char $sname\[] =\n";
+    print OUT_FILE "{\n";
+    file_to_hex($fname);
+    print OUT_FILE "};\n";
+    print OUT_FILE "static const int sizeof_$sname = sizeof($sname);\n\n";
+}
+
+print OUT_FILE "#endif /* HAVE_PQC && HAVE_SPHINCS */\n\n";
+
 # convert and print 256-bit cert/keys
 print OUT_FILE "#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)\n\n";
 for (my $i = 0; $i < $num_ecc; $i++) {
diff --git a/rpm/spec.in b/rpm/spec.in
index 4fb5e61d1..8b60193e1 100644
--- a/rpm/spec.in
+++ b/rpm/spec.in
@@ -269,6 +269,7 @@ mkdir -p $RPM_BUILD_ROOT/
 %{_includedir}/wolfssl/wolfcrypt/error-crypt.h
 %{_includedir}/wolfssl/wolfcrypt/falcon.h
 %{_includedir}/wolfssl/wolfcrypt/dilithium.h
+%{_includedir}/wolfssl/wolfcrypt/sphincs.h
 %{_includedir}/wolfssl/wolfcrypt/fe_448.h
 %{_includedir}/wolfssl/wolfcrypt/fe_operations.h
 %{_includedir}/wolfssl/wolfcrypt/fips_test.h
@@ -318,8 +319,9 @@ mkdir -p $RPM_BUILD_ROOT/
 %changelog
 * Tue Aug 30 2022 Jacob Barthelmeh <jacob@wolfssl.com>
 - Add include of QUIC documentation
-- Add a new header dilithium.h.
-* Wed Jul 20 2022 Anthony Hu <anthony@wolfssl.com>
+* Wed Aug 17 2022 Anthony Hu <anthony@wolfssl.com>
+- Add a new header sphincs.h.
+* Fri Jul 20 2022 Anthony Hu <anthony@wolfssl.com>
 - Add a new header dilithium.h.
 * Fri Jul 8 2022 Jacob Barthelmeh <jacob@wolfssl.com>
 - Add missing sp_int.h file
diff --git a/src/include.am b/src/include.am
index 064d59ee7..ab12ae4e9 100644
--- a/src/include.am
+++ b/src/include.am
@@ -662,6 +662,7 @@ endif
 if BUILD_LIBOQS
 src_libwolfssl_la_SOURCES += wolfcrypt/src/falcon.c
 src_libwolfssl_la_SOURCES += wolfcrypt/src/dilithium.c
+src_libwolfssl_la_SOURCES += wolfcrypt/src/sphincs.c
 endif
 
 if BUILD_LIBZ
diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c
index 32047f277..c31d2c222 100644
--- a/wolfcrypt/benchmark/benchmark.c
+++ b/wolfcrypt/benchmark/benchmark.c
@@ -262,16 +262,19 @@
 #endif
 #ifdef HAVE_LIBOQS
     #include <oqs/kem.h>
+    #include <oqs/sig.h>
 #endif
+
 #if defined(HAVE_PQC)
     #if defined(HAVE_FALCON)
         #include <wolfssl/wolfcrypt/falcon.h>
     #endif
-#endif
-#if defined(HAVE_PQC)
     #if defined(HAVE_DILITHIUM)
         #include <wolfssl/wolfcrypt/dilithium.h>
     #endif
+    #if defined(HAVE_SPHINCS)
+        #include <wolfssl/wolfcrypt/sphincs.h>
+    #endif
 #endif
 
 #ifdef HAVE_PQM4
@@ -483,6 +486,14 @@
 #define BENCH_DILITHIUM_AES_LEVEL3_SIGN 0x40000000
 #define BENCH_DILITHIUM_AES_LEVEL5_SIGN 0x80000000
 
+/* Post-Quantum Asymmetric algorithms. (Part 2) */
+#define BENCH_SPHINCS_FAST_LEVEL1_SIGN  0x00000001
+#define BENCH_SPHINCS_FAST_LEVEL3_SIGN  0x00000002
+#define BENCH_SPHINCS_FAST_LEVEL5_SIGN  0x00000004
+#define BENCH_SPHINCS_SMALL_LEVEL1_SIGN 0x00000008
+#define BENCH_SPHINCS_SMALL_LEVEL3_SIGN 0x00000010
+#define BENCH_SPHINCS_SMALL_LEVEL5_SIGN 0x00000020
+
 /* Other */
 #define BENCH_RNG                0x00000001
 #define BENCH_SCRYPT             0x00000002
@@ -503,6 +514,8 @@ static int bench_mac_algs = 0;
 static int bench_asym_algs = 0;
 /* Post-Quantum Asymmetric algorithms to benchmark. */
 static int bench_pq_asym_algs = 0;
+/* Post-Quantum Asymmetric algorithms to benchmark. (Part 2)*/
+static int bench_pq_asym_algs2 = 0;
 /* Other cryptographic algorithms to benchmark. */
 static int bench_other_algs = 0;
 
@@ -764,7 +777,6 @@ static const bench_pq_alg bench_pq_asym_opt[] = {
       OQS_SIG_alg_dilithium_3_aes },
     { "-dilithium_aes_level5", BENCH_DILITHIUM_AES_LEVEL5_SIGN,
       OQS_SIG_alg_dilithium_5_aes },
-
     { "-kyber_level1-kg",    BENCH_KYBER_LEVEL1_KEYGEN,
       OQS_KEM_alg_kyber_512 },
     { "-kyber_level1-ed",       BENCH_KYBER_LEVEL1_ENCAP,
@@ -813,10 +825,31 @@ static const bench_pq_alg bench_pq_asym_opt[] = {
       OQS_KEM_alg_ntru_hps4096821 },
     { "-ntruHPS_level5-ed",     BENCH_NTRUHPS_LEVEL5_ENCAP,
       OQS_KEM_alg_ntru_hps4096821 },
-#endif
+#endif /* HAVE_LIBOQS */
     { NULL, 0, NULL }
 };
-#endif
+
+#ifdef HAVE_LIBOQS
+/* All recognized post-quantum asymmetric algorithm choosing command line
+ * options. (Part 2) */
+static const bench_pq_alg bench_pq_asym_opt2[] = {
+    { "-pq",                 0xffffffff, NULL},
+    { "-sphincs_fast_level1", BENCH_SPHINCS_FAST_LEVEL1_SIGN,
+      OQS_SIG_alg_sphincs_shake256_128f_simple },
+    { "-sphincs_fast_level3", BENCH_SPHINCS_FAST_LEVEL3_SIGN,
+      OQS_SIG_alg_sphincs_shake256_192f_simple },
+    { "-sphincs_fast_level5", BENCH_SPHINCS_FAST_LEVEL5_SIGN,
+      OQS_SIG_alg_sphincs_shake256_256f_simple },
+    { "-sphincs_small_level1", BENCH_SPHINCS_SMALL_LEVEL1_SIGN,
+      OQS_SIG_alg_sphincs_shake256_128s_simple },
+    { "-sphincs_small_level3", BENCH_SPHINCS_SMALL_LEVEL3_SIGN,
+      OQS_SIG_alg_sphincs_shake256_192s_simple },
+    { "-sphincs_small_level5", BENCH_SPHINCS_SMALL_LEVEL5_SIGN,
+      OQS_SIG_alg_sphincs_shake256_256s_simple },
+    { NULL, 0, NULL }
+};
+#endif /* HAVE_LIBOQS */
+#endif /* HAVE_PQC */
 
 #ifdef HAVE_WNR
     const char* wnrConfigFile = "wnr-example.conf";
@@ -2374,6 +2407,20 @@ static void* benchmarks_do(void* args)
         bench_dilithiumKeySign(5, AES_VARIANT);
 #endif
 
+#ifdef HAVE_SPHINCS
+    if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_FAST_LEVEL1_SIGN))
+        bench_sphincsKeySign(1, FAST_VARIANT);
+    if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_FAST_LEVEL3_SIGN))
+        bench_sphincsKeySign(3, FAST_VARIANT);
+    if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_FAST_LEVEL5_SIGN))
+        bench_sphincsKeySign(5, FAST_VARIANT);
+    if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_SMALL_LEVEL1_SIGN))
+        bench_sphincsKeySign(1, SMALL_VARIANT);
+    if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_SMALL_LEVEL3_SIGN))
+        bench_sphincsKeySign(3, SMALL_VARIANT);
+    if (bench_all || (bench_pq_asym_algs2 & BENCH_SPHINCS_SMALL_LEVEL5_SIGN))
+        bench_sphincsKeySign(5, SMALL_VARIANT);
+#endif
 #endif /* HAVE_LIBOQS */
 
 #ifdef WOLFCRYPT_HAVE_SAKKE
@@ -2419,6 +2466,7 @@ exit:
     (void)bench_asym_algs;
     (void)bench_other_algs;
     (void)bench_pq_asym_algs;
+    (void)bench_pq_asym_algs2;
 
     return NULL;
 }
@@ -7455,6 +7503,145 @@ void bench_dilithiumKeySign(byte level, byte sym)
     wc_dilithium_free(&key);
 }
 #endif /* HAVE_DILITHIUM */
+
+#ifdef HAVE_SPHINCS
+void bench_sphincsKeySign(byte level, byte optim)
+{
+    int    ret = 0;
+    sphincs_key key;
+    double start;
+    int    i, count;
+    byte   sig[SPHINCS_MAX_SIG_SIZE];
+    byte   msg[512];
+    word32 x = 0;
+    const char**desc = bench_desc_words[lng_index];
+
+    ret = wc_sphincs_init(&key);
+    if (ret != 0) {
+        printf("wc_sphincs_init failed %d\n", ret);
+        return;
+    }
+
+    ret = wc_sphincs_set_level_and_optim(&key, level, optim);
+    if (ret != 0) {
+        printf("wc_sphincs_set_level_and_optim() failed %d\n", ret);
+    }
+
+    if (ret == 0) {
+        ret = -1;
+        if ((level == 1) && (optim == FAST_VARIANT)) {
+            ret = wc_sphincs_import_private_key(bench_sphincs_fast_level1_key,
+                      sizeof_bench_sphincs_fast_level1_key, NULL, 0, &key);
+        }
+        else if ((level == 3) && (optim == FAST_VARIANT)) {
+            ret = wc_sphincs_import_private_key(bench_sphincs_fast_level3_key,
+                      sizeof_bench_sphincs_fast_level3_key, NULL, 0, &key);
+        }
+        else if ((level == 5) && (optim == FAST_VARIANT)) {
+            ret = wc_sphincs_import_private_key(bench_sphincs_fast_level5_key,
+                      sizeof_bench_sphincs_fast_level5_key, NULL, 0, &key);
+        }
+        else if ((level == 1) && (optim == SMALL_VARIANT)) {
+            ret = wc_sphincs_import_private_key(
+                      bench_sphincs_small_level1_key,
+                      sizeof_bench_sphincs_small_level1_key, NULL, 0, &key);
+        }
+        else if ((level == 3) && (optim == SMALL_VARIANT)) {
+            ret = wc_sphincs_import_private_key(
+                      bench_sphincs_small_level3_key,
+                      sizeof_bench_sphincs_small_level3_key, NULL, 0, &key);
+        }
+        else if ((level == 5) && (optim == SMALL_VARIANT)) {
+            ret = wc_sphincs_import_private_key(
+                      bench_sphincs_small_level5_key,
+                      sizeof_bench_sphincs_small_level5_key, NULL, 0, &key);
+        }
+
+        if (ret != 0) {
+            printf("wc_sphincs_import_private_key failed %d\n", ret);
+        }
+    }
+
+    /* make dummy msg */
+    for (i = 0; i < (int)sizeof(msg); i++) {
+        msg[i] = (byte)i;
+    }
+
+    bench_stats_start(&count, &start);
+    do {
+        for (i = 0; i < agreeTimes; i++) {
+            if (ret == 0) {
+                if ((level == 1) && (optim == FAST_VARIANT)) {
+                    x = SPHINCS_FAST_LEVEL1_SIG_SIZE;
+                }
+                else if ((level == 3) && (optim == FAST_VARIANT)) {
+                    x = SPHINCS_FAST_LEVEL3_SIG_SIZE;
+                }
+                else if ((level == 5) && (optim == FAST_VARIANT)) {
+                    x = SPHINCS_FAST_LEVEL5_SIG_SIZE;
+                }
+                else if ((level == 1) && (optim == SMALL_VARIANT)) {
+                    x = SPHINCS_SMALL_LEVEL1_SIG_SIZE;
+                }
+                else if ((level == 3) && (optim == SMALL_VARIANT)) {
+                    x = SPHINCS_SMALL_LEVEL3_SIG_SIZE;
+                }
+                else if ((level == 5) && (optim == SMALL_VARIANT)) {
+                    x = SPHINCS_SMALL_LEVEL5_SIG_SIZE;
+                }
+
+                ret = wc_sphincs_sign_msg(msg, sizeof(msg), sig, &x, &key);
+                if (ret != 0) {
+                    printf("wc_sphincs_sign_msg failed\n");
+                }
+            }
+        }
+        count += i;
+    } while (bench_stats_sym_check(start));
+
+    if (ret == 0) {
+        if (optim == FAST_VARIANT) {
+            bench_stats_asym_finish("SPHINCS-FAST", level, desc[4], 0, count,
+                                    start, ret);
+        }
+        else {
+            bench_stats_asym_finish("SPHINCS-SMALL", level, desc[4], 0, count,
+                                    start, ret);
+        }
+    }
+
+    bench_stats_start(&count, &start);
+    do {
+        for (i = 0; i < agreeTimes; i++) {
+            if (ret == 0) {
+                int verify = 0;
+                ret = wc_sphincs_verify_msg(sig, x, msg, sizeof(msg), &verify,
+                                            &key);
+
+                if (ret != 0 || verify != 1) {
+                    printf("wc_sphincs_verify_msg failed %d, verify %d\n",
+                           ret, verify);
+                    ret = -1;
+                }
+            }
+        }
+        count += i;
+    } while (bench_stats_sym_check(start));
+
+    if (ret == 0) {
+        if (optim == FAST_VARIANT) {
+            bench_stats_asym_finish("SPHINCS-FAST", level, desc[5], 0, count,
+                                    start, ret);
+        }
+        else {
+            bench_stats_asym_finish("SPHINCS-SMALL", level, desc[5], 0, count,
+                                    start, ret);
+        }
+    }
+
+    wc_sphincs_free(&key);
+}
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
 
 #ifndef HAVE_STACK_SIZE
@@ -7786,8 +7973,18 @@ static void Usage(void)
     line = 13;
     for (i=0; bench_other_opt[i].str != NULL; i++)
         print_alg(bench_other_opt[i].str + 1, &line);
+    printf("\n             ");
+#if defined(HAVE_PQC)
+    line = 13;
+    for (i=0; bench_pq_asym_opt[i].str != NULL; i++)
+        print_alg(bench_pq_asym_opt[i].str + 1, &line);
+#if defined(HAVE_LIBOQS)
+    for (i=0; bench_pq_asym_opt2[i].str != NULL; i++)
+        print_alg(bench_pq_asym_opt2[i].str + 1, &line);
     printf("\n");
-#endif
+#endif /* HAVE_LIBOQS */
+#endif /* HAVE_PQC */
+#endif /* !WOLFSSL_BENCHMARK_ALL */
     printf("%s", bench_Usage_msg1[lng_index][14]);   /* option -lng */
     printf("%s", bench_Usage_msg1[lng_index][15]);   /* option <num> */
 #ifdef WC_ENABLE_BENCH_THREADING
@@ -7963,7 +8160,20 @@ int main(int argc, char** argv)
                     optMatched = 1;
                 }
             }
-        #endif
+        #if defined(HAVE_LIBOQS)
+            /* Both bench_pq_asym_opt and bench_pq_asym_opt2 are looking for
+             * -pq, so we need to reset optMatched in case it was set to 1 just
+             * above. */
+            optMatched = 0;
+            for (i=0; !optMatched && bench_pq_asym_opt2[i].str != NULL; i++) {
+                if (string_matches(argv[1], bench_pq_asym_opt2[i].str)) {
+                    bench_pq_asym_algs2 |= bench_pq_asym_opt2[i].val;
+                    bench_all = 0;
+                    optMatched = 1;
+                }
+            }
+        #endif /* HAVE_LIBOQS*/
+        #endif /* HAVE_PQC */
             /* Other known cryptographic algorithms */
             for (i=0; !optMatched && bench_other_opt[i].str != NULL; i++) {
                 if (string_matches(argv[1], bench_other_opt[i].str)) {
diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h
index eafb262ab..2cc16d14c 100644
--- a/wolfcrypt/benchmark/benchmark.h
+++ b/wolfcrypt/benchmark/benchmark.h
@@ -109,6 +109,7 @@ void bench_blake2s(void);
 void bench_pbkdf2(void);
 void bench_falconKeySign(byte level);
 void bench_dilithiumKeySign(byte level, byte sym);
+void bench_sphincsKeySign(byte level, byte optim);
 void bench_pqcKemKeygen(word32 alg);
 void bench_pqcKemEncapDecap(word32 alg);
 
diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c
index abfa27ee1..0716d8a5e 100644
--- a/wolfcrypt/src/asn.c
+++ b/wolfcrypt/src/asn.c
@@ -148,6 +148,9 @@ ASN Options:
     #if defined(HAVE_DILITHIUM)
     #include <wolfssl/wolfcrypt/dilithium.h>
     #endif
+    #if defined(HAVE_SPHINCS)
+    #include <wolfssl/wolfcrypt/sphincs.h>
+    #endif
 #endif
 
 #ifdef WOLFSSL_QNX_CAAM
@@ -4017,6 +4020,31 @@ static word32 SetBitString16Bit(word16 val, byte* output)
     static const byte sigDilithiumAes_Level5Oid[] =
         {43, 6, 1, 4, 1, 2, 130, 11, 11, 8, 7};
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+    /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */
+    static const byte sigSphincsFast_Level1Oid[] =
+        {43, 206, 15, 6, 7, 4};
+
+    /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */
+    static const byte sigSphincsFast_Level3Oid[] =
+        {43, 206, 15, 6, 8, 3};
+
+    /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */
+    static const byte sigSphincsFast_Level5Oid[] =
+        {43, 206, 15, 6, 9, 3};
+
+    /* Sphincs Small Level 1: 1 3 9999 6 7 10 */
+    static const byte sigSphincsSmall_Level1Oid[] =
+        {43, 206, 15, 6, 7, 10};
+
+    /* Sphincs Small Level 3: 1 3 9999 6 8 7 */
+    static const byte sigSphincsSmall_Level3Oid[] =
+        {43, 206, 15, 6, 8, 7};
+
+    /* Sphincs Small Level 5: 1 3 9999 6 9 7 */
+    static const byte sigSphincsSmall_Level5Oid[] =
+        {43, 206, 15, 6, 9, 7};
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
 
 /* keyType */
@@ -4080,6 +4108,31 @@ static word32 SetBitString16Bit(word16 val, byte* output)
     static const byte keyDilithiumAes_Level5Oid[] =
         {43, 6, 1, 4, 1, 2, 130, 11, 11, 8, 7};
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+    /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */
+    static const byte keySphincsFast_Level1Oid[] =
+        {43, 206, 15, 6, 7, 4};
+
+    /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */
+    static const byte keySphincsFast_Level3Oid[] =
+        {43, 206, 15, 6, 8, 3};
+
+    /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */
+    static const byte keySphincsFast_Level5Oid[] =
+        {43, 206, 15, 6, 9, 3};
+
+    /* Sphincs Small Level 1: 1 3 9999 6 7 10 */
+    static const byte keySphincsSmall_Level1Oid[] =
+        {43, 206, 15, 6, 7, 10};
+
+    /* Sphincs Small Level 3: 1 3 9999 6 8 7 */
+    static const byte keySphincsSmall_Level3Oid[] =
+        {43, 206, 15, 6, 8, 7};
+
+    /* Sphincs Small Level 5: 1 3 9999 6 9 7 */
+    static const byte keySphincsSmall_Level5Oid[] =
+        {43, 206, 15, 6, 9, 7};
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
 
 /* curveType */
@@ -4614,6 +4667,32 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
                     *oidSz = sizeof(sigDilithiumAes_Level5Oid);
                     break;
                 #endif /* HAVE_DILITHIUM */
+                #ifdef HAVE_SPHINCS
+                case CTC_SPHINCS_FAST_LEVEL1:
+                    oid = sigSphincsFast_Level1Oid;
+                    *oidSz = sizeof(sigSphincsFast_Level1Oid);
+                    break;
+                case CTC_SPHINCS_FAST_LEVEL3:
+                    oid = sigSphincsFast_Level3Oid;
+                    *oidSz = sizeof(sigSphincsFast_Level3Oid);
+                    break;
+                case CTC_SPHINCS_FAST_LEVEL5:
+                    oid = sigSphincsFast_Level5Oid;
+                    *oidSz = sizeof(sigSphincsFast_Level5Oid);
+                    break;
+                case CTC_SPHINCS_SMALL_LEVEL1:
+                    oid = sigSphincsSmall_Level1Oid;
+                    *oidSz = sizeof(sigSphincsSmall_Level1Oid);
+                    break;
+                case CTC_SPHINCS_SMALL_LEVEL3:
+                    oid = sigSphincsSmall_Level3Oid;
+                    *oidSz = sizeof(sigSphincsSmall_Level3Oid);
+                    break;
+                case CTC_SPHINCS_SMALL_LEVEL5:
+                    oid = sigSphincsSmall_Level5Oid;
+                    *oidSz = sizeof(sigSphincsSmall_Level5Oid);
+                    break;
+                #endif /* HAVE_SPHINCS */
                 #endif /* HAVE_PQC */
                 default:
                     break;
@@ -4713,6 +4792,32 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
                     *oidSz = sizeof(keyDilithiumAes_Level5Oid);
                     break;
                 #endif /* HAVE_DILITHIUM */
+                #ifdef HAVE_SPHINCS
+                case SPHINCS_FAST_LEVEL1k:
+                    oid = keySphincsFast_Level1Oid;
+                    *oidSz = sizeof(keySphincsFast_Level1Oid);
+                    break;
+                case SPHINCS_FAST_LEVEL3k:
+                    oid = keySphincsFast_Level3Oid;
+                    *oidSz = sizeof(keySphincsFast_Level3Oid);
+                    break;
+                case SPHINCS_FAST_LEVEL5k:
+                    oid = keySphincsFast_Level5Oid;
+                    *oidSz = sizeof(keySphincsFast_Level5Oid);
+                    break;
+                case SPHINCS_SMALL_LEVEL1k:
+                    oid = keySphincsSmall_Level1Oid;
+                    *oidSz = sizeof(keySphincsSmall_Level1Oid);
+                    break;
+                case SPHINCS_SMALL_LEVEL3k:
+                    oid = keySphincsSmall_Level3Oid;
+                    *oidSz = sizeof(keySphincsSmall_Level3Oid);
+                    break;
+                case SPHINCS_SMALL_LEVEL5k:
+                    oid = keySphincsSmall_Level5Oid;
+                    *oidSz = sizeof(keySphincsSmall_Level5Oid);
+                    break;
+                #endif /* HAVE_SPHINCS */
                 #endif /* HAVE_PQC */
                 default:
                     break;
@@ -5575,16 +5680,15 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
 {
     int    ret = 0;
     word32 idx = *inOutIdx;
-#ifdef HAVE_PQC
-    int found_collision = 0;
-#endif /* HAVE_PQC */
 #ifndef NO_VERIFY_OID
     word32 actualOidSz;
     const byte* actualOid;
     const byte* checkOid = NULL;
     word32 checkOidSz;
 #endif /* NO_VERIFY_OID */
-
+#ifdef HAVE_PQC
+    word32 found_collision = 0;
+#endif
     (void)oidType;
     *oid = 0;
 
@@ -5609,13 +5713,20 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
      *
      * As a small hack, we're going to look for the special case of
      * DILITHIUM_AES_LEVEL3k and if we find it, instead of *oid being set to 220
-     * we will set it to 221. This hack will hopefully disappear when new
-     * standardized OIDs appear. Note that DILITHIUM_AES_LEVEL3k is defined to
-     * be 221.
+     * we will set it to 221. Note that DILITHIUM_AES_LEVEL3k is defined as 221.
+     *
+     * Same thing for SPHINCS_FAST_LEVEL1 and SPHINCS_FAST_LEVEL3. We will look
+     * for the special case of SPHINCS_FAST_LEVEL3 and set *oid to 283 instead
+     * of 281; 282 is taken.
+     *
+     * These hacks will hopefully disappear when new standardized OIDs appear.
      */
-    if (memcmp(sigDilithiumAes_Level3Oid, &input[idx],
-        sizeof(sigDilithiumAes_Level3Oid)) == 0) {
-        found_collision = 1;
+    if (memcmp(&input[idx], sigDilithiumAes_Level3Oid,
+                sizeof(sigDilithiumAes_Level3Oid)) == 0) {
+        found_collision = DILITHIUM_AES_LEVEL3k;
+    } else if (memcmp(&input[idx], sigSphincsFast_Level3Oid,
+                sizeof(sigSphincsFast_Level3Oid)) == 0) {
+        found_collision = SPHINCS_FAST_LEVEL3k;
     }
 #endif /* HAVE_PQC */
 
@@ -5628,7 +5739,7 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
 
 #ifdef HAVE_PQC
     if (found_collision) {
-        *oid = DILITHIUM_AES_LEVEL3k;
+        *oid = found_collision;
     }
 #endif /* HAVE_PQC */
 
@@ -6672,7 +6783,7 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
                 break;
         #endif
             /* DSAk not supported. */
-            /* Falcon and Dilithium not supported. */
+            /* Falcon, Dilithium and Sphincs not supported. */
             /* Ignore OID lookup failures. */
             default:
                 break;
@@ -7220,7 +7331,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
         }
         if ((ret = wc_Falcon_PrivateKeyDecode(privKey, &keyIdx, key_pair,
                                              privKeySz)) == 0) {
-            WOLFSSL_MSG("Checking Falcon_ key pair");
+            WOLFSSL_MSG("Checking Falcon key pair");
             keyIdx = 0;
             if ((ret = wc_falcon_import_public(pubKey, pubKeySz,
                                                key_pair)) == 0) {
@@ -7298,7 +7409,7 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
         }
         if ((ret = wc_Dilithium_PrivateKeyDecode(privKey, &keyIdx, key_pair,
                                              privKeySz)) == 0) {
-            WOLFSSL_MSG("Checking Dilithium_ key pair");
+            WOLFSSL_MSG("Checking Dilithium key pair");
             keyIdx = 0;
             if ((ret = wc_dilithium_import_public(pubKey, pubKeySz,
                                                key_pair)) == 0) {
@@ -7314,6 +7425,77 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
     }
     else
     #endif /* HAVE_DILITHIUM */
+    #if defined(HAVE_SPHINCS)
+    if ((ks == SPHINCS_FAST_LEVEL1k) ||
+        (ks == SPHINCS_FAST_LEVEL3k) ||
+        (ks == SPHINCS_FAST_LEVEL5k) ||
+        (ks == SPHINCS_SMALL_LEVEL1k) ||
+        (ks == SPHINCS_SMALL_LEVEL3k) ||
+        (ks == SPHINCS_SMALL_LEVEL5k)) {
+    #ifdef WOLFSSL_SMALL_STACK
+        sphincs_key* key_pair = NULL;
+    #else
+        sphincs_key  key_pair[1];
+    #endif
+        word32     keyIdx = 0;
+
+    #ifdef WOLFSSL_SMALL_STACK
+        key_pair = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL,
+                                        DYNAMIC_TYPE_SPHINCS);
+        if (key_pair == NULL)
+            return MEMORY_E;
+    #endif
+        ret = wc_sphincs_init(key_pair);
+        if (ret  < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
+    #endif
+            return ret;
+        }
+
+        if (ks == SPHINCS_FAST_LEVEL1k) {
+            ret = wc_sphincs_set_level_and_optim(key_pair, 1, FAST_VARIANT);
+        }
+        else if (ks == SPHINCS_FAST_LEVEL3k) {
+            ret = wc_sphincs_set_level_and_optim(key_pair, 3, FAST_VARIANT);
+        }
+        else if (ks == SPHINCS_FAST_LEVEL5k) {
+            ret = wc_sphincs_set_level_and_optim(key_pair, 5, FAST_VARIANT);
+        }
+        else if (ks == SPHINCS_SMALL_LEVEL1k) {
+            ret = wc_sphincs_set_level_and_optim(key_pair, 1, SMALL_VARIANT);
+        }
+        else if (ks == SPHINCS_SMALL_LEVEL3k) {
+            ret = wc_sphincs_set_level_and_optim(key_pair, 3, SMALL_VARIANT);
+        }
+        else if (ks == SPHINCS_SMALL_LEVEL5k) {
+            ret = wc_sphincs_set_level_and_optim(key_pair, 5, SMALL_VARIANT);
+        }
+
+        if (ret  < 0) {
+    #ifdef WOLFSSL_SMALL_STACK
+            XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
+    #endif
+            return ret;
+        }
+        if ((ret = wc_Sphincs_PrivateKeyDecode(privKey, &keyIdx, key_pair,
+                                             privKeySz)) == 0) {
+            WOLFSSL_MSG("Checking Sphincs key pair");
+            keyIdx = 0;
+            if ((ret = wc_sphincs_import_public(pubKey, pubKeySz,
+                                               key_pair)) == 0) {
+                /* Public and private extracted successfully. Sanity check. */
+                if ((ret = wc_sphincs_check_key(key_pair)) == 0)
+                    ret = 1;
+            }
+        }
+        wc_sphincs_free(key_pair);
+    #ifdef WOLFSSL_SMALL_STACK
+        XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
+    #endif
+    }
+    else
+    #endif /* HAVE_SPHINCS */
     #endif /* HAVE_PQC */
     {
         ret = 0;
@@ -7730,6 +7912,83 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
         XFREE(dilithium, heap, DYNAMIC_TYPE_TMP_BUFFER);
     }
 #endif /* HAVE_DILITHIUM */
+#if defined(HAVE_SPHINCS)
+    if (*algoID == 0) {
+        sphincs_key *sphincs = (sphincs_key *)XMALLOC(sizeof(*sphincs),
+             heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (sphincs == NULL)
+            return MEMORY_E;
+
+        if (wc_sphincs_init(sphincs) != 0) {
+            tmpIdx = 0;
+            if (wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT)
+                == 0) {
+                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
+                    keySz) == 0) {
+                    *algoID = SPHINCS_FAST_LEVEL1k;
+                }
+                else {
+                    WOLFSSL_MSG("Not Sphincs-fast Level 1 DER key");
+                }
+            }
+            else if (wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT)
+                == 0) {
+                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
+                    keySz) == 0) {
+                    *algoID = SPHINCS_FAST_LEVEL3k;
+                }
+                else {
+                    WOLFSSL_MSG("Not Sphincs-fast Level 3 DER key");
+                }
+            }
+            else if (wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT)
+                == 0) {
+                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
+                    keySz) == 0) {
+                    *algoID = SPHINCS_FAST_LEVEL5k;
+                }
+                else {
+                    WOLFSSL_MSG("Not Sphincs-fast Level 5 DER key");
+                }
+            }
+            else if (wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT)
+                == 0) {
+                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
+                    keySz) == 0) {
+                    *algoID = SPHINCS_SMALL_LEVEL1k;
+                }
+                else {
+                    WOLFSSL_MSG("Not Sphincs-small Level 1 DER key");
+                }
+            }
+            else if (wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT)
+                == 0) {
+                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
+                    keySz) == 0) {
+                    *algoID = SPHINCS_SMALL_LEVEL3k;
+                }
+                else {
+                    WOLFSSL_MSG("Not Sphincs-small Level 3 DER key");
+                }
+            }
+            else if (wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT)
+                == 0) {
+                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
+                    keySz) == 0) {
+                    *algoID = SPHINCS_SMALL_LEVEL5k;
+                }
+                else {
+                    WOLFSSL_MSG("Not Sphincs-small Level 5 DER key");
+                }
+            }
+            else {
+                WOLFSSL_MSG("GetKeyOID sphincs initialization failed");
+            }
+            wc_sphincs_free(sphincs);
+        }
+        XFREE(sphincs, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
 
     /* if flag is not set then this is not a key that we understand. */
@@ -11537,6 +11796,32 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
             ret = StoreKey(cert, source, &srcIdx, maxIdx);
             break;
     #endif /* HAVE_DILITHIUM */
+    #ifdef HAVE_SPHINCS
+        case SPHINCS_FAST_LEVEL1k:
+            cert->pkCurveOID = SPHINCS_FAST_LEVEL1k;
+            ret = StoreKey(cert, source, &srcIdx, maxIdx);
+            break;
+        case SPHINCS_FAST_LEVEL3k:
+            cert->pkCurveOID = SPHINCS_FAST_LEVEL3k;
+            ret = StoreKey(cert, source, &srcIdx, maxIdx);
+            break;
+        case SPHINCS_FAST_LEVEL5k:
+            cert->pkCurveOID = SPHINCS_FAST_LEVEL5k;
+            ret = StoreKey(cert, source, &srcIdx, maxIdx);
+            break;
+        case SPHINCS_SMALL_LEVEL1k:
+            cert->pkCurveOID = SPHINCS_SMALL_LEVEL1k;
+            ret = StoreKey(cert, source, &srcIdx, maxIdx);
+            break;
+        case SPHINCS_SMALL_LEVEL3k:
+            cert->pkCurveOID = SPHINCS_SMALL_LEVEL3k;
+            ret = StoreKey(cert, source, &srcIdx, maxIdx);
+            break;
+        case SPHINCS_SMALL_LEVEL5k:
+            cert->pkCurveOID = SPHINCS_SMALL_LEVEL5k;
+            ret = StoreKey(cert, source, &srcIdx, maxIdx);
+            break;
+    #endif /* HAVE_SPHINCS */
     #endif /* HAVE_PQC */
     #ifndef NO_DSA
         case DSAk:
@@ -14517,6 +14802,14 @@ static WC_INLINE int IsSigAlgoECC(int algoOID)
               || (algoOID == DILITHIUM_AES_LEVEL3k)
               || (algoOID == DILITHIUM_AES_LEVEL5k)
         #endif
+        #ifdef HAVE_SPHINCS
+              || (algoOID == SPHINCS_FAST_LEVEL1k)
+              || (algoOID == SPHINCS_FAST_LEVEL3k)
+              || (algoOID == SPHINCS_FAST_LEVEL5k)
+              || (algoOID == SPHINCS_SMALL_LEVEL1k)
+              || (algoOID == SPHINCS_SMALL_LEVEL3k)
+              || (algoOID == SPHINCS_SMALL_LEVEL5k)
+        #endif
         #endif /* HAVE_PQC */
     );
 }
@@ -14829,6 +15122,19 @@ void FreeSignatureCtx(SignatureCtx* sigCtx)
                 sigCtx->key.dilithium = NULL;
                 break;
         #endif /* HAVE_DILITHIUM */
+        #if defined(HAVE_SPHINCS)
+            case SPHINCS_FAST_LEVEL1k:
+            case SPHINCS_FAST_LEVEL3k:
+            case SPHINCS_FAST_LEVEL5k:
+            case SPHINCS_SMALL_LEVEL1k:
+            case SPHINCS_SMALL_LEVEL3k:
+            case SPHINCS_SMALL_LEVEL5k:
+                wc_sphincs_free(sigCtx->key.sphincs);
+                XFREE(sigCtx->key.sphincs, sigCtx->heap,
+                      DYNAMIC_TYPE_SPHINCS);
+                sigCtx->key.sphincs = NULL;
+                break;
+        #endif /* HAVE_SPHINCS */
         #endif /* HAVE_PQC  */
             default:
                 break;
@@ -14984,6 +15290,16 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
             /* Hashes done in signing operation. */
             break;
     #endif
+    #ifdef HAVE_SPHINCS
+        case CTC_SPHINCS_FAST_LEVEL1:
+        case CTC_SPHINCS_FAST_LEVEL3:
+        case CTC_SPHINCS_FAST_LEVEL5:
+        case CTC_SPHINCS_SMALL_LEVEL1:
+        case CTC_SPHINCS_SMALL_LEVEL3:
+        case CTC_SPHINCS_SMALL_LEVEL5:
+            /* Hashes done in signing operation. */
+            break;
+    #endif
     #endif /* HAVE_PQC */
 
         default:
@@ -15532,6 +15848,159 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
                     break;
                 }
             #endif /* HAVE_DILITHIUM */
+            #if defined(HAVE_SPHINCS)
+                case SPHINCS_FAST_LEVEL1k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.sphincs =
+                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
+                                             sigCtx->heap,
+                                             DYNAMIC_TYPE_SPHINCS);
+                    if (sigCtx->key.sphincs == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_set_level_and_optim(
+                                   sigCtx->key.sphincs, 1, FAST_VARIANT))
+                        < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_import_public(key, keySz,
+                        sigCtx->key.sphincs)) < 0) {
+                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1");
+                        goto exit_cs;
+                    }
+                    break;
+                }
+                case SPHINCS_FAST_LEVEL3k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.sphincs =
+                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
+                                             sigCtx->heap,
+                                             DYNAMIC_TYPE_SPHINCS);
+                    if (sigCtx->key.sphincs == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_set_level_and_optim(
+                                   sigCtx->key.sphincs, 3, FAST_VARIANT))
+                        < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_import_public(key, keySz,
+                        sigCtx->key.sphincs)) < 0) {
+                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3");
+                        goto exit_cs;
+                    }
+                    break;
+                }
+                case SPHINCS_FAST_LEVEL5k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.sphincs =
+                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
+                                             sigCtx->heap,
+                                             DYNAMIC_TYPE_SPHINCS);
+                    if (sigCtx->key.sphincs == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_set_level_and_optim(
+                                   sigCtx->key.sphincs, 5, FAST_VARIANT))
+                        < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_import_public(key, keySz,
+                        sigCtx->key.sphincs)) < 0) {
+                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5");
+                        goto exit_cs;
+                    }
+                    break;
+                }
+
+                case SPHINCS_SMALL_LEVEL1k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.sphincs =
+                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
+                                             sigCtx->heap,
+                                             DYNAMIC_TYPE_SPHINCS);
+                    if (sigCtx->key.sphincs == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_set_level_and_optim(
+                                   sigCtx->key.sphincs, 1, SMALL_VARIANT))
+                        < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_import_public(key, keySz,
+                        sigCtx->key.sphincs)) < 0) {
+                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1");
+                        goto exit_cs;
+                    }
+                    break;
+                }
+                case SPHINCS_SMALL_LEVEL3k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.sphincs =
+                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
+                                             sigCtx->heap,
+                                             DYNAMIC_TYPE_SPHINCS);
+                    if (sigCtx->key.sphincs == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_set_level_and_optim(
+                                   sigCtx->key.sphincs, 3, SMALL_VARIANT))
+                        < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_import_public(key, keySz,
+                        sigCtx->key.sphincs)) < 0) {
+                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3");
+                        goto exit_cs;
+                    }
+                    break;
+                }
+                case SPHINCS_SMALL_LEVEL5k:
+                {
+                    sigCtx->verify = 0;
+                    sigCtx->key.sphincs =
+                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
+                                             sigCtx->heap,
+                                             DYNAMIC_TYPE_SPHINCS);
+                    if (sigCtx->key.sphincs == NULL) {
+                        ERROR_OUT(MEMORY_E, exit_cs);
+                    }
+                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_set_level_and_optim(
+                                   sigCtx->key.sphincs, 5, SMALL_VARIANT))
+                        < 0) {
+                        goto exit_cs;
+                    }
+                    if ((ret = wc_sphincs_import_public(key, keySz,
+                        sigCtx->key.sphincs)) < 0) {
+                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5");
+                        goto exit_cs;
+                    }
+                    break;
+                }
+            #endif /* HAVE_SPHINCS */
             #endif /* HAVE_PQC */
                 default:
                     WOLFSSL_MSG("Verify Key type unknown");
@@ -15668,6 +16137,20 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
                     break;
                 }
             #endif /* HAVE_DILITHIUM */
+            #if defined(HAVE_SPHINCS)
+                case SPHINCS_FAST_LEVEL1k:
+                case SPHINCS_FAST_LEVEL3k:
+                case SPHINCS_FAST_LEVEL5k:
+                case SPHINCS_SMALL_LEVEL1k:
+                case SPHINCS_SMALL_LEVEL3k:
+                case SPHINCS_SMALL_LEVEL5k:
+                {
+                    ret = wc_sphincs_verify_msg(sig, sigSz, buf, bufSz,
+                                                &sigCtx->verify,
+                                                sigCtx->key.sphincs);
+                    break;
+                }
+            #endif /* HAVE_SPHINCS */
             #endif /* HAVE_PQC */
                 default:
                     break;
@@ -15908,6 +16391,74 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
                     break;
                 }
             #endif /* HAVE_DILITHIUM */
+            #ifdef HAVE_SPHINCS
+                case SPHINCS_FAST_LEVEL1k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL1 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+                case SPHINCS_FAST_LEVEL3k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL3 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+                case SPHINCS_FAST_LEVEL5k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL5 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+                case SPHINCS_SMALL_LEVEL1k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL1 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+                case SPHINCS_SMALL_LEVEL3k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL3 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+                case SPHINCS_SMALL_LEVEL5k:
+                {
+                    if (sigCtx->verify == 1) {
+                        ret = 0;
+                    }
+                    else {
+                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL5 Verify didn't match");
+                        ret = ASN_SIG_CONFIRM_E;
+                    }
+                    break;
+                }
+            #endif /* HAVE_SPHINCS */
             #endif /* HAVE_PQC */
                 default:
                     break;
@@ -21939,6 +22490,21 @@ wcchar END_PUB_KEY          = "-----END PUBLIC KEY-----";
     wcchar BEGIN_DILITHIUM_AES_LEVEL5_PRIV = "-----BEGIN DILITHIUM_AES_LEVEL5 PRIVATE KEY-----";
     wcchar END_DILITHIUM_AES_LEVEL5_PRIV   = "-----END DILITHIUM_AES_LEVEL5 PRIVATE KEY-----";
 #endif /* HAVE_DILITHIUM */
+#if defined(HAVE_SPHINCS)
+    wcchar BEGIN_SPHINCS_FAST_LEVEL1_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL1 PRIVATE KEY-----";
+    wcchar END_SPHINCS_FAST_LEVEL1_PRIV   = "-----END SPHINCS_FAST_LEVEL1 PRIVATE KEY-----";
+    wcchar BEGIN_SPHINCS_FAST_LEVEL3_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL3 PRIVATE KEY-----";
+    wcchar END_SPHINCS_FAST_LEVEL3_PRIV   = "-----END SPHINCS_FAST_LEVEL3 PRIVATE KEY-----";
+    wcchar BEGIN_SPHINCS_FAST_LEVEL5_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL5 PRIVATE KEY-----";
+    wcchar END_SPHINCS_FAST_LEVEL5_PRIV   = "-----END SPHINCS_FAST_LEVEL5 PRIVATE KEY-----";
+
+    wcchar BEGIN_SPHINCS_SMALL_LEVEL1_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----";
+    wcchar END_SPHINCS_SMALL_LEVEL1_PRIV   = "-----END SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----";
+    wcchar BEGIN_SPHINCS_SMALL_LEVEL3_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----";
+    wcchar END_SPHINCS_SMALL_LEVEL3_PRIV   = "-----END SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----";
+    wcchar BEGIN_SPHINCS_SMALL_LEVEL5_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----";
+    wcchar END_SPHINCS_SMALL_LEVEL5_PRIV   = "-----END SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----";
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
 
 const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----"
@@ -22079,6 +22645,38 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
             ret = 0;
             break;
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+        case SPHINCS_FAST_LEVEL1_TYPE:
+            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL1_PRIV;
+            if (footer) *footer = END_SPHINCS_FAST_LEVEL1_PRIV;
+            ret = 0;
+            break;
+        case SPHINCS_FAST_LEVEL3_TYPE:
+            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL3_PRIV;
+            if (footer) *footer = END_SPHINCS_FAST_LEVEL3_PRIV;
+            ret = 0;
+            break;
+        case SPHINCS_FAST_LEVEL5_TYPE:
+            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL5_PRIV;
+            if (footer) *footer = END_SPHINCS_FAST_LEVEL5_PRIV;
+            ret = 0;
+            break;
+        case SPHINCS_SMALL_LEVEL1_TYPE:
+            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL1_PRIV;
+            if (footer) *footer = END_SPHINCS_SMALL_LEVEL1_PRIV;
+            ret = 0;
+            break;
+        case SPHINCS_SMALL_LEVEL3_TYPE:
+            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL3_PRIV;
+            if (footer) *footer = END_SPHINCS_SMALL_LEVEL3_PRIV;
+            ret = 0;
+            break;
+        case SPHINCS_SMALL_LEVEL5_TYPE:
+            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL5_PRIV;
+            if (footer) *footer = END_SPHINCS_SMALL_LEVEL5_PRIV;
+            ret = 0;
+            break;
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
         case PUBLICKEY_TYPE:
         case ECC_PUBLICKEY_TYPE:
@@ -26720,7 +27318,7 @@ static int SetValidity(byte* before, byte* after, int daysValid)
 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
                       WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
                       ed448_key* ed448Key, falcon_key* falconKey,
-                      dilithium_key* dilithiumKey)
+                      dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
 {
     int ret;
 
@@ -26730,7 +27328,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
     /* make sure at least one key type is provided */
     if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
         dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
-        dilithiumKey == NULL) {
+        dilithiumKey == NULL && sphincsKey == NULL) {
         return PUBLIC_KEY_E;
     }
 
@@ -26833,6 +27431,21 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
                                      (word32)sizeof(der->publicKey), 1);
     }
 #endif /* HAVE_DILITHIUM */
+#if defined(HAVE_SPHINCS)
+    if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) ||
+        (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) ||
+        (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) ||
+        (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) ||
+        (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) ||
+        (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) {
+        if (sphincsKey == NULL)
+            return PUBLIC_KEY_E;
+
+        der->publicKeySz =
+            wc_Sphincs_PublicKeyToDer(sphincsKey, der->publicKey,
+                                      (word32)sizeof(der->publicKey), 1);
+    }
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
 
     if (der->publicKeySz <= 0)
@@ -27227,7 +27840,8 @@ static int WriteCertBody(DerCert* der, byte* buf)
 static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
     byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
     ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
-    dilithium_key* dilithiumKey, WC_RNG* rng, int sigAlgoType, void* heap)
+    dilithium_key* dilithiumKey, sphincs_key* sphincsKey, WC_RNG* rng,
+    int sigAlgoType, void* heap)
 {
     int digestSz = 0, typeH = 0, ret = 0;
 
@@ -27243,6 +27857,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
     (void)ed448Key;
     (void)falconKey;
     (void)dilithiumKey;
+    (void)sphincsKey;
     (void)rng;
     (void)heap;
 
@@ -27343,6 +27958,15 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
                 ret = outSz;
         }
     #endif /* HAVE_DILITHIUM */
+    #if defined(HAVE_SPHINCS)
+        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && !falconKey &&
+            !dilithiumKey && sphincsKey) {
+            word32 outSz = sigSz;
+            ret = wc_sphincs_sign_msg(buf, sz, sig, &outSz, sphincsKey);
+            if (ret == 0)
+                ret = outSz;
+        }
+    #endif /* HAVE_SPHINCS */
     #endif /* HAVE_PQC */
 
         break;
@@ -27524,7 +28148,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
                        RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
                        DsaKey* dsaKey, ed25519_key* ed25519Key,
                        ed448_key* ed448Key, falcon_key* falconKey,
-                       dilithium_key* dilithiumKey)
+                       dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
 {
 #ifndef WOLFSSL_ASN_TEMPLATE
     int ret;
@@ -27574,6 +28198,26 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
              && (dilithiumKey->sym == AES_VARIANT))
         cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+             && (sphincsKey->optim == FAST_VARIANT))
+        cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+             && (sphincsKey->optim == FAST_VARIANT))
+        cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+             && (sphincsKey->optim == FAST_VARIANT))
+        cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+             && (sphincsKey->optim == SMALL_VARIANT))
+        cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+             && (sphincsKey->optim == SMALL_VARIANT))
+        cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+             && (sphincsKey->optim == SMALL_VARIANT))
+        cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
     else
         return BAD_FUNC_ARG;
@@ -27585,7 +28229,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
 #endif
 
     ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
-                     ed448Key, falconKey, dilithiumKey);
+                     ed448Key, falconKey, dilithiumKey, sphincsKey);
     if (ret == 0) {
         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
             ret = BUFFER_E;
@@ -27610,8 +28254,10 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
     word32 issRawLen = 0;
     word32 sbjRawLen = 0;
 
-    (void)falconKey;    /* Unused without OQS */
-    (void)dilithiumKey; /* Unused without OQS */
+    /* Unused without OQS */
+    (void)falconKey;
+    (void)dilithiumKey;
+    (void)sphincsKey;
 
     CALLOC_ASNSETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
 
@@ -27667,6 +28313,32 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
             cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
         }
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+                 && (sphincsKey->optim == FAST_VARIANT)) {
+            cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+                 && (sphincsKey->optim == FAST_VARIANT)) {
+            cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+                 && (sphincsKey->optim == FAST_VARIANT)) {
+            cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+                 && (sphincsKey->optim == SMALL_VARIANT)) {
+            cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+                 && (sphincsKey->optim == SMALL_VARIANT)) {
+            cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+                 && (sphincsKey->optim == SMALL_VARIANT)) {
+            cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
+        }
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
         else {
             ret = BAD_FUNC_ARG;
@@ -27908,6 +28580,7 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
     ed448_key*         ed448Key = NULL;
     falcon_key*        falconKey = NULL;
     dilithium_key*     dilithiumKey = NULL;
+    sphincs_key*       sphincsKey = NULL;
 
     if (keyType == RSA_TYPE)
         rsaKey = (RsaKey*)key;
@@ -27935,9 +28608,22 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
         dilithiumKey = (dilithium_key*)key;
     else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
         dilithiumKey = (dilithium_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
 
     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey,
-                       ed25519Key, ed448Key, falconKey, dilithiumKey);
+                       ed25519Key, ed448Key, falconKey, dilithiumKey,
+                       sphincsKey);
 }
 
 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
@@ -27946,7 +28632,7 @@ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
              ecc_key* eccKey, WC_RNG* rng)
 {
     return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL,
-                       NULL, NULL, NULL);
+                       NULL, NULL, NULL, NULL);
 }
 
 #ifdef WOLFSSL_CERT_REQ
@@ -28110,7 +28796,8 @@ static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz,
 static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
                          DsaKey* dsaKey, ecc_key* eccKey,
                          ed25519_key* ed25519Key, ed448_key* ed448Key,
-                         falcon_key* falconKey, dilithium_key* dilithiumKey)
+                         falcon_key* falconKey, dilithium_key* dilithiumKey,
+                         sphincs_key* sphincsKey)
 {
     int ret;
 
@@ -28119,6 +28806,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
     (void)ed448Key;
     (void)falconKey;
     (void)dilithiumKey;
+    (void)sphincsKey;
 
     if (cert == NULL || der == NULL)
         return BAD_FUNC_ARG;
@@ -28230,6 +28918,19 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
             der->publicKey, (word32)sizeof(der->publicKey), 1);
     }
 #endif
+#if defined(HAVE_SPHINCS)
+    if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) ||
+        (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) ||
+        (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) ||
+        (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) ||
+        (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) ||
+        (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) {
+        if (sphincsKey == NULL)
+            return PUBLIC_KEY_E;
+        der->publicKeySz = wc_Sphincs_PublicKeyToDer(sphincsKey,
+            der->publicKey, (word32)sizeof(der->publicKey), 1);
+    }
+#endif
 #endif /* HAVE_PQC */
 
     if (der->publicKeySz <= 0)
@@ -28514,7 +29215,8 @@ enum {
 static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
                    RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
                    ed25519_key* ed25519Key, ed448_key* ed448Key,
-                   falcon_key* falconKey, dilithium_key* dilithiumKey)
+                   falcon_key* falconKey, dilithium_key* dilithiumKey,
+                   sphincs_key* sphincsKey)
 {
 #ifndef WOLFSSL_ASN_TEMPLATE
     int ret;
@@ -28561,6 +29263,26 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
              && (dilithiumKey->sym == AES_VARIANT))
         cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+             && (sphincsKey->optim == FAST_VARIANT))
+        cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+             && (sphincsKey->optim == FAST_VARIANT))
+        cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+             && (sphincsKey->optim == FAST_VARIANT))
+        cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+             && (sphincsKey->optim == SMALL_VARIANT))
+        cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+             && (sphincsKey->optim == SMALL_VARIANT))
+        cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
+    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+             && (sphincsKey->optim == SMALL_VARIANT))
+        cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
     else
         return BAD_FUNC_ARG;
@@ -28573,7 +29295,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
 #endif
 
     ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
-                        falconKey, dilithiumKey);
+                        falconKey, dilithiumKey, sphincsKey);
 
     if (ret == 0) {
         if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
@@ -28601,6 +29323,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
     /* Unused without OQS */
     (void)falconKey;
     (void)dilithiumKey;
+    (void)sphincsKey;
 
     CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap);
 
@@ -28656,6 +29379,32 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
             cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
         }
 #endif /* HAVE_DILITHIUM */
+#ifdef HAVE_SPHINCS
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+                 && (sphincsKey->optim == FAST_VARIANT)) {
+            cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+                 && (sphincsKey->optim == FAST_VARIANT)) {
+            cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+                 && (sphincsKey->optim == FAST_VARIANT)) {
+            cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
+                 && (sphincsKey->optim == SMALL_VARIANT)) {
+            cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
+                 && (sphincsKey->optim == SMALL_VARIANT)) {
+            cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
+        }
+        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
+                 && (sphincsKey->optim == SMALL_VARIANT)) {
+            cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
+        }
+#endif /* HAVE_SPHINCS */
 #endif /* HAVE_PQC */
         else {
             ret = BAD_FUNC_ARG;
@@ -28804,6 +29553,7 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
     ed448_key*     ed448Key = NULL;
     falcon_key*    falconKey = NULL;
     dilithium_key* dilithiumKey = NULL;
+    sphincs_key*   sphincsKey = NULL;
 
     if (keyType == RSA_TYPE)
         rsaKey = (RsaKey*)key;
@@ -28831,9 +29581,22 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
         dilithiumKey = (dilithium_key*)key;
     else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
         dilithiumKey = (dilithium_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
 
     return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey,
-                       ed25519Key, ed448Key, falconKey, dilithiumKey);
+                       ed25519Key, ed448Key, falconKey, dilithiumKey,
+                       sphincsKey);
 }
 
 WOLFSSL_ABI
@@ -28841,7 +29604,7 @@ int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
                    RsaKey* rsaKey, ecc_key* eccKey)
 {
     return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL,
-                       NULL, NULL, NULL);
+                       NULL, NULL, NULL, NULL);
 }
 #endif /* WOLFSSL_CERT_REQ */
 
@@ -28849,7 +29612,8 @@ int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
 static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
                     RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
                     ed448_key* ed448Key, falcon_key* falconKey,
-                    dilithium_key* dilithiumKey, WC_RNG* rng)
+                    dilithium_key* dilithiumKey, sphincs_key* sphincsKey,
+                    WC_RNG* rng)
 {
     int sigSz = 0;
     void* heap = NULL;
@@ -28903,7 +29667,7 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
 
     sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig,
         MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
-        falconKey, dilithiumKey, rng, sType, heap);
+        falconKey, dilithiumKey, sphincsKey, rng, sType, heap);
 #ifdef WOLFSSL_ASYNC_CRYPT
     if (sigSz == WC_PENDING_E) {
         /* Not free'ing certSignCtx->sig here because it could still be in use
@@ -28935,6 +29699,7 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
     ed448_key*         ed448Key = NULL;
     falcon_key*        falconKey = NULL;
     dilithium_key*     dilithiumKey = NULL;
+    sphincs_key*       sphincsKey = NULL;
 
     if (keyType == RSA_TYPE)
         rsaKey = (RsaKey*)key;
@@ -28960,16 +29725,28 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
         dilithiumKey = (dilithium_key*)key;
     else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
         dilithiumKey = (dilithium_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
 
     return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
-                    ed448Key, falconKey, dilithiumKey, rng);
+                    ed448Key, falconKey, dilithiumKey, sphincsKey, rng);
 }
 
 int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
                 RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
 {
     return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
-                    NULL, NULL, rng);
+                    NULL, NULL, NULL, rng);
 }
 
 WOLFSSL_ABI
@@ -29006,14 +29783,16 @@ int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
 static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
                                  ed25519_key* ed25519Key, ed448_key* ed448Key,
                                  falcon_key* falconKey,
-                                 dilithium_key* dilithiumKey, int kid_type)
+                                 dilithium_key* dilithiumKey,
+                                 sphincs_key *sphincsKey, int kid_type)
 {
     byte *buf;
     int   bufferSz, ret;
 
     if (cert == NULL ||
         (rsakey == NULL && eckey == NULL && ed25519Key == NULL &&
-         ed448Key == NULL && falconKey == NULL && dilithiumKey == NULL) ||
+         ed448Key == NULL && falconKey == NULL && dilithiumKey == NULL &&
+         sphincsKey == NULL) ||
         (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
         return BAD_FUNC_ARG;
 
@@ -29059,6 +29838,12 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
                                                MAX_PUBLIC_KEY_SZ, 0);
     }
 #endif
+#if defined(HAVE_SPHINCS)
+    if (sphincsKey != NULL) {
+        bufferSz = wc_Sphincs_PublicKeyToDer(sphincsKey, buf,
+                                               MAX_PUBLIC_KEY_SZ, 0);
+    }
+#endif
 #endif /* HAVE_PQC */
 
     if (bufferSz <= 0) {
@@ -29090,6 +29875,7 @@ int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
     ed448_key*         ed448Key = NULL;
     falcon_key*        falconKey = NULL;
     dilithium_key*     dilithiumKey = NULL;
+    sphincs_key*       sphincsKey = NULL;
 
     if (keyType == RSA_TYPE)
         rsaKey = (RsaKey*)key;
@@ -29115,16 +29901,29 @@ int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
         dilithiumKey = (dilithium_key*)key;
     else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
         dilithiumKey = (dilithium_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
 
     return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
-                                 falconKey, dilithiumKey, SKID_TYPE);
+                                 falconKey, dilithiumKey, sphincsKey,
+                                 SKID_TYPE);
 }
 
 /* Set SKID from RSA or ECC public key */
 int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
 {
     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
-                                 SKID_TYPE);
+                                 NULL, SKID_TYPE);
 }
 
 int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
@@ -29135,6 +29934,7 @@ int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
     ed448_key*         ed448Key = NULL;
     falcon_key*        falconKey = NULL;
     dilithium_key*     dilithiumKey = NULL;
+    sphincs_key*       sphincsKey = NULL;
 
     if (keyType == RSA_TYPE)
         rsaKey = (RsaKey*)key;
@@ -29160,16 +29960,29 @@ int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
         dilithiumKey = (dilithium_key*)key;
     else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
         dilithiumKey = (dilithium_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
+        sphincsKey = (sphincs_key*)key;
+    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
+        sphincsKey = (sphincs_key*)key;
 
     return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
-                                 falconKey, dilithiumKey, AKID_TYPE);
+                                 falconKey, dilithiumKey, sphincsKey,
+                                 AKID_TYPE);
 }
 
 /* Set SKID from RSA or ECC public key */
 int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
 {
     return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
-                                 AKID_TYPE);
+                                 NULL, AKID_TYPE);
 }
 
 
@@ -31911,7 +32724,8 @@ enum {
     || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \
     || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
     || (defined(HAVE_PQC) && defined(HAVE_FALCON)) \
-    || (defined(HAVE_PQC) && defined(HAVE_DILITHIUM)))
+    || (defined(HAVE_PQC) && defined(HAVE_DILITHIUM)) \
+    || (defined(HAVE_PQC) && defined(HAVE_SPHINCS)))
 
 int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
     byte* privKey, word32* privKeyLen,
diff --git a/wolfcrypt/src/sphincs.c b/wolfcrypt/src/sphincs.c
new file mode 100644
index 000000000..8b8658549
--- /dev/null
+++ b/wolfcrypt/src/sphincs.c
@@ -0,0 +1,1053 @@
+/* sphincs.c
+ *
+ * Copyright (C) 2006-2022 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+/* Based on dilithium.c and Reworked for Sphincs by Anthony Hu. */
+
+#ifdef HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+/* in case user set HAVE_PQC there */
+#include <wolfssl/wolfcrypt/settings.h>
+
+#include <wolfssl/wolfcrypt/asn.h>
+
+#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
+
+#ifdef HAVE_LIBOQS
+#include <oqs/oqs.h>
+#endif
+
+#include <wolfssl/wolfcrypt/sphincs.h>
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#ifdef NO_INLINE
+    #include <wolfssl/wolfcrypt/misc.h>
+#else
+    #define WOLFSSL_MISC_INCLUDED
+    #include <wolfcrypt/src/misc.c>
+#endif
+
+/* Sign the message using the sphincs private key.
+ *
+ *  in          [in]      Message to sign.
+ *  inLen       [in]      Length of the message in bytes.
+ *  out         [in]      Buffer to write signature into.
+ *  outLen      [in/out]  On in, size of buffer.
+ *                        On out, the length of the signature in bytes.
+ *  key         [in]      Sphincs key to use when signing
+ *  returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
+ *          BUFFER_E when outLen is less than SPHINCS_FAST_LEVEL1_SIG_SIZE,
+ *          0 otherwise.
+ */
+int wc_sphincs_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
+                        sphincs_key* key)
+{
+    int ret = 0;
+#ifdef HAVE_LIBOQS
+    OQS_SIG *oqssig = NULL;
+    size_t localOutLen = 0;
+
+    /* sanity check on arguments */
+    if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if ((ret == 0) && (!key->prvKeySet)) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        if ((key->optim == FAST_VARIANT) && (key->level == 1)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_128f_simple);
+        }
+        else if ((key->optim == FAST_VARIANT) && (key->level == 3)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_192f_simple);
+        }
+        else if ((key->optim == FAST_VARIANT) && (key->level == 5)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_256f_simple);
+        }
+        else if ((key->optim == SMALL_VARIANT) && (key->level == 1)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_128s_simple);
+        }
+        else if ((key->optim == SMALL_VARIANT) && (key->level == 3)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_192s_simple);
+        }
+        else if ((key->optim == SMALL_VARIANT) && (key->level == 5)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_256s_simple);
+        }
+
+        if (oqssig == NULL) {
+            ret = SIG_TYPE_E;
+        }
+    }
+
+    /* check and set up out length */
+    if (ret == 0) {
+        if ((key->level == 1) && (key->optim == FAST_VARIANT) &&
+            (*outLen < SPHINCS_FAST_LEVEL1_SIG_SIZE)) {
+            *outLen = SPHINCS_FAST_LEVEL1_SIG_SIZE;
+            ret = BUFFER_E;
+        }
+        else if ((key->level == 3) && (key->optim == FAST_VARIANT) &&
+            (*outLen < SPHINCS_FAST_LEVEL3_SIG_SIZE)) {
+            *outLen = SPHINCS_FAST_LEVEL3_SIG_SIZE;
+            ret = BUFFER_E;
+        }
+        else if ((key->level == 5) && (key->optim == FAST_VARIANT) &&
+            (*outLen < SPHINCS_FAST_LEVEL5_SIG_SIZE)) {
+            *outLen = SPHINCS_FAST_LEVEL5_SIG_SIZE;
+            ret = BUFFER_E;
+        }
+        else if ((key->level == 1) && (key->optim == SMALL_VARIANT) &&
+            (*outLen < SPHINCS_SMALL_LEVEL1_SIG_SIZE)) {
+            *outLen = SPHINCS_SMALL_LEVEL1_SIG_SIZE;
+            ret = BUFFER_E;
+        }
+        else if ((key->level == 3) && (key->optim == SMALL_VARIANT) &&
+            (*outLen < SPHINCS_SMALL_LEVEL3_SIG_SIZE)) {
+            *outLen = SPHINCS_SMALL_LEVEL3_SIG_SIZE;
+            ret = BUFFER_E;
+        }
+        else if ((key->level == 5) && (key->optim == SMALL_VARIANT) &&
+            (*outLen < SPHINCS_SMALL_LEVEL5_SIG_SIZE)) {
+            *outLen = SPHINCS_SMALL_LEVEL5_SIG_SIZE;
+            ret = BUFFER_E;
+        }
+
+        localOutLen = *outLen;
+    }
+
+    if ((ret == 0) &&
+        (OQS_SIG_sign(oqssig, out, &localOutLen, in, inLen, key->k)
+         == OQS_ERROR)) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        *outLen = (word32)localOutLen;
+    }
+
+    if (oqssig != NULL) {
+        OQS_SIG_free(oqssig);
+    }
+#else
+    ret = NOT_COMPILED_IN;
+#endif
+    return ret;
+}
+
+/* Verify the message using the sphincs public key.
+ *
+ *  sig         [in]  Signature to verify.
+ *  sigLen      [in]  Size of signature in bytes.
+ *  msg         [in]  Message to verify.
+ *  msgLen      [in]  Length of the message in bytes.
+ *  res         [out] *res is set to 1 on successful verification.
+ *  key         [in]  Sphincs key to use to verify.
+ *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
+ *          BUFFER_E when sigLen is less than SPHINCS_FAST_LEVEL1_SIG_SIZE,
+ *          0 otherwise.
+ */
+int wc_sphincs_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
+                          word32 msgLen, int* res, sphincs_key* key)
+{
+    int ret = 0;
+#ifdef HAVE_LIBOQS
+    OQS_SIG *oqssig = NULL;
+
+    if (key == NULL || sig == NULL || msg == NULL || res == NULL) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if ((ret == 0) && (!key->pubKeySet)) {
+        ret = BAD_FUNC_ARG;
+    }
+
+    if (ret == 0) {
+        if ((key->optim == FAST_VARIANT) && (key->level == 1)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_128f_simple);
+        }
+        else if ((key->optim == FAST_VARIANT) && (key->level == 3)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_192f_simple);
+        }
+        else if ((key->optim == FAST_VARIANT) && (key->level == 5)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_256f_simple);
+        }
+        else if ((key->optim == SMALL_VARIANT) && (key->level == 1)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_128s_simple);
+        }
+        else if ((key->optim == SMALL_VARIANT) && (key->level == 3)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_192s_simple);
+        }
+        else if ((key->optim == SMALL_VARIANT) && (key->level == 5)) {
+            oqssig = OQS_SIG_new(OQS_SIG_alg_sphincs_shake256_256s_simple);
+        }
+
+        if (oqssig == NULL) {
+            ret = SIG_TYPE_E;
+        }
+    }
+
+    if ((ret == 0) &&
+        (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p)
+         == OQS_ERROR)) {
+         ret = SIG_VERIFY_E;
+    }
+
+    if (ret == 0) {
+        *res = 1;
+    }
+
+    if (oqssig != NULL) {
+        OQS_SIG_free(oqssig);
+    }
+#else
+    ret = NOT_COMPILED_IN;
+#endif
+
+    return ret;
+}
+
+/* Initialize the sphincs private/public key.
+ *
+ * key  [in]  Sphincs key.
+ * returns BAD_FUNC_ARG when key is NULL
+ */
+int wc_sphincs_init(sphincs_key* key)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    ForceZero(key, sizeof(key));
+    return 0;
+}
+
+/* Set the level of the sphincs private/public key.
+ *
+ * key   [out]  Sphincs key.
+ * level [in]   Either 2,3 or 5.
+ * optim [in]   Either FAST_VARIANT or SMALL_VARIANT.
+ * returns BAD_FUNC_ARG when key is NULL or level or optim are bad values.
+ */
+int wc_sphincs_set_level_and_optim(sphincs_key* key, byte level, byte optim)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (level != 1 && level != 3 && level != 5) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (optim != FAST_VARIANT && optim != SMALL_VARIANT) {
+        return BAD_FUNC_ARG;
+    }
+
+    key->level = level;
+    key->optim = optim;
+    key->pubKeySet = 0;
+    key->prvKeySet = 0;
+    return 0;
+}
+
+/* Get the level and optimization variant of the sphincs private/public key.
+ *
+ * key   [in]  Sphincs key.
+ * level [out] The level.
+ * optim [out] The optimization variant. FAST_VARIANT or SMALL_VARIANT.
+ * returns BAD_FUNC_ARG when key is NULL or level has not been set.
+ */
+int wc_sphincs_get_level_and_optim(sphincs_key* key, byte* level, byte* optim)
+{
+    if (key == NULL || level == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (key->level != 1 && key->level != 3 && key->level != 5) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (key->optim != FAST_VARIANT && key->optim != SMALL_VARIANT) {
+        return BAD_FUNC_ARG;
+    }
+
+    *level = key->level;
+    *optim = key->optim;
+    return 0;
+}
+
+/* Clears the sphincs key data
+ *
+ * key  [in]  Sphincs key.
+ */
+void wc_sphincs_free(sphincs_key* key)
+{
+    if (key != NULL) {
+        ForceZero(key, sizeof(key));
+    }
+}
+
+/* Export the sphincs public key.
+ *
+ * key     [in]      Sphincs public key.
+ * out     [in]      Array to hold public key.
+ * outLen  [in/out]  On in, the number of bytes in array.
+ *                   On out, the number bytes put into array.
+ * returns BAD_FUNC_ARG when a parameter is NULL,
+ *         BUFFER_E when outLen is less than SPHINCS_FAST_LEVEL1_PUB_KEY_SIZE,
+ *         0 otherwise.
+ */
+int wc_sphincs_export_public(sphincs_key* key,
+                             byte* out, word32* outLen)
+{
+    /* sanity check on arguments */
+    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level != 1) && (key->level != 5)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (!key->pubKeySet) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* check and set up out length */
+    if ((key->level == 1) && (*outLen < SPHINCS_LEVEL1_PUB_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL1_PUB_KEY_SIZE;
+        return BUFFER_E;
+    }
+    else if ((key->level == 3) && (*outLen < SPHINCS_LEVEL3_PUB_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL3_PUB_KEY_SIZE;
+        return BUFFER_E;
+    }
+    else if ((key->level == 5) && (*outLen < SPHINCS_LEVEL5_PUB_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL5_PUB_KEY_SIZE;
+        return BUFFER_E;
+    }
+
+    if (key->level == 1) {
+        *outLen = SPHINCS_LEVEL1_PUB_KEY_SIZE;
+        XMEMCPY(out, key->p, SPHINCS_LEVEL1_PUB_KEY_SIZE);
+    }
+    else if (key->level == 3) {
+        *outLen = SPHINCS_LEVEL3_PUB_KEY_SIZE;
+        XMEMCPY(out, key->p, SPHINCS_LEVEL3_PUB_KEY_SIZE);
+    }
+    else if (key->level == 5) {
+        *outLen = SPHINCS_LEVEL5_PUB_KEY_SIZE;
+        XMEMCPY(out, key->p, SPHINCS_LEVEL5_PUB_KEY_SIZE);
+    }
+
+    return 0;
+}
+
+/* Import a sphincs public key from a byte array.
+ * Public key encoded in big-endian.
+ *
+ * in      [in]  Array holding public key.
+ * inLen   [in]  Number of bytes of data in array.
+ * key     [in]  Sphincs public key.
+ * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
+ *         0 otherwise.
+ */
+int wc_sphincs_import_public(const byte* in, word32 inLen,
+                             sphincs_key* key)
+{
+    /* sanity check on arguments */
+    if ((in == NULL) || (key == NULL)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level != 1) && (key->level != 3) && (key->level != 5)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (inLen != SPHINCS_LEVEL1_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+    else if ((key->level == 3) && (inLen != SPHINCS_LEVEL3_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+    else if ((key->level == 5) && (inLen != SPHINCS_LEVEL5_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+
+    XMEMCPY(key->p, in, inLen);
+    key->pubKeySet = 1;
+
+    return 0;
+}
+
+static int parse_private_key(const byte* priv, word32 privSz,
+                             byte** out, word32 *outSz,
+                             sphincs_key* key) {
+    word32 idx = 0;
+    int ret = 0;
+    int length = 0;
+
+    /* sanity check on arguments */
+    if ((priv == NULL) || (key == NULL)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level != 1) && (key->level != 3) && (key->level != 5)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* At this point, it is still a PKCS8 private key. */
+    if ((ret = ToTraditionalInline(priv, &idx, privSz)) < 0) {
+        return ret;
+    }
+
+    /* Now it is a octet_string(concat(priv,pub)) */
+    if ((ret = GetOctetString(priv, &idx, &length, privSz)) < 0) {
+        return ret;
+    }
+
+    *out = (byte *)priv + idx;
+    *outSz = privSz - idx;
+
+    /* And finally it is concat(priv,pub). Key size check. */
+    if ((key->level == 1) && (*outSz != SPHINCS_LEVEL1_KEY_SIZE +
+                                        SPHINCS_LEVEL1_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+    else if ((key->level == 3) && (*outSz != SPHINCS_LEVEL3_KEY_SIZE +
+                                             SPHINCS_LEVEL3_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+    else if ((key->level == 5) && (*outSz != SPHINCS_LEVEL5_KEY_SIZE +
+                                             SPHINCS_LEVEL5_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+
+    return 0;
+}
+
+/* Import a sphincs private key from a byte array.
+ *
+ * priv    [in]  Array holding private key.
+ * privSz  [in]  Number of bytes of data in array.
+ * key     [in]  Sphincs private key.
+ * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
+ *         SPHINCS_LEVEL1_KEY_SIZE,
+ *         0 otherwise.
+ */
+int wc_sphincs_import_private_only(const byte* priv, word32 privSz,
+                                   sphincs_key* key)
+{
+    int ret = 0;
+    byte *newPriv = NULL;
+    word32 newPrivSz = 0;
+
+    if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
+        != 0) {
+         return ret;
+    }
+
+    if (key->level == 1) {
+        XMEMCPY(key->k, newPriv, SPHINCS_LEVEL1_KEY_SIZE);
+    }
+    else if (key->level == 3) {
+        XMEMCPY(key->k, newPriv, SPHINCS_LEVEL3_KEY_SIZE);
+    }
+    else if (key->level == 5) {
+        XMEMCPY(key->k, newPriv, SPHINCS_LEVEL5_KEY_SIZE);
+    }
+    key->prvKeySet = 1;
+
+    return 0;
+}
+
+/* Import a sphincs private and public keys from byte array(s).
+ *
+ * priv    [in]  Array holding private key or private+public keys
+ * privSz  [in]  Number of bytes of data in private key array.
+ * pub     [in]  Array holding public key (or NULL).
+ * pubSz   [in]  Number of bytes of data in public key array (or 0).
+ * key     [in]  Sphincs private/public key.
+ * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
+ *         combination of keys/lengths is supplied, 0 otherwise.
+ */
+int wc_sphincs_import_private_key(const byte* priv, word32 privSz,
+                                  const byte* pub, word32 pubSz,
+                                  sphincs_key* key)
+{
+    int ret = 0;
+    byte *newPriv = NULL;
+    word32 newPrivSz = 0;
+
+    if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
+        != 0) {
+         return ret;
+    }
+
+    if (pub == NULL) {
+        if (pubSz != 0) {
+            return BAD_FUNC_ARG;
+        }
+
+        if ((newPrivSz != SPHINCS_LEVEL1_PRV_KEY_SIZE) &&
+            (newPrivSz != SPHINCS_LEVEL3_PRV_KEY_SIZE) &&
+            (newPrivSz != SPHINCS_LEVEL5_PRV_KEY_SIZE)) {
+            return BAD_FUNC_ARG;
+        }
+
+        if (key->level == 1) {
+            pub = newPriv + SPHINCS_LEVEL1_KEY_SIZE;
+            pubSz = SPHINCS_LEVEL1_PUB_KEY_SIZE;
+        }
+        else if (key->level == 3) {
+            pub = newPriv + SPHINCS_LEVEL3_KEY_SIZE;
+            pubSz = SPHINCS_LEVEL3_PUB_KEY_SIZE;
+        }
+        else if (key->level == 5) {
+            pub = newPriv + SPHINCS_LEVEL5_KEY_SIZE;
+            pubSz = SPHINCS_LEVEL5_PUB_KEY_SIZE;
+        }
+    }
+    else if ((pubSz != SPHINCS_LEVEL1_PUB_KEY_SIZE) &&
+             (pubSz != SPHINCS_LEVEL3_PUB_KEY_SIZE) &&
+             (pubSz != SPHINCS_LEVEL5_PUB_KEY_SIZE)) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* import public key */
+    ret = wc_sphincs_import_public(pub, pubSz, key);
+
+    if (ret == 0) {
+        /* make the private key (priv + pub) */
+        if (key->level == 1) {
+            XMEMCPY(key->k, newPriv, SPHINCS_LEVEL1_KEY_SIZE);
+        }
+        else if (key->level == 3) {
+            XMEMCPY(key->k, newPriv, SPHINCS_LEVEL3_KEY_SIZE);
+        }
+        else if (key->level == 5) {
+            XMEMCPY(key->k, newPriv, SPHINCS_LEVEL5_KEY_SIZE);
+        }
+        key->prvKeySet = 1;
+    }
+
+    return ret;
+}
+
+/* Export the sphincs private key.
+ *
+ * key     [in]      Sphincs private key.
+ * out     [in]      Array to hold private key.
+ * outLen  [in/out]  On in, the number of bytes in array.
+ *                   On out, the number bytes put into array.
+ * returns BAD_FUNC_ARG when a parameter is NULL,
+ *         BUFFER_E when outLen is less than SPHINCS_LEVEL1_KEY_SIZE,
+ *         0 otherwise.
+ */
+int wc_sphincs_export_private_only(sphincs_key* key, byte* out, word32* outLen)
+{
+    /* sanity checks on arguments */
+    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level != 1) && (key->level != 3) && (key->level != 5)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* check and set up out length */
+    if ((key->level == 1) && (*outLen < SPHINCS_LEVEL1_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL1_KEY_SIZE;
+        return BUFFER_E;
+    }
+    else if ((key->level == 3) && (*outLen < SPHINCS_LEVEL3_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL3_KEY_SIZE;
+        return BUFFER_E;
+    }
+    else if ((key->level == 5) && (*outLen < SPHINCS_LEVEL5_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL5_KEY_SIZE;
+        return BUFFER_E;
+    }
+
+    if (key->level == 1) {
+        *outLen = SPHINCS_LEVEL1_KEY_SIZE;
+    }
+    else if (key->level == 3) {
+        *outLen = SPHINCS_LEVEL3_KEY_SIZE;
+    }
+    else if (key->level == 5) {
+        *outLen = SPHINCS_LEVEL5_KEY_SIZE;
+    }
+
+    XMEMCPY(out, key->k, *outLen);
+
+    return 0;
+}
+
+/* Export the sphincs private and public key.
+ *
+ * key     [in]      Sphincs private/public key.
+ * out     [in]      Array to hold private and public key.
+ * outLen  [in/out]  On in, the number of bytes in array.
+ *                   On out, the number bytes put into array.
+ * returns BAD_FUNC_ARG when a parameter is NULL,
+ *         BUFFER_E when outLen is less than required, 0 otherwise.
+ */
+int wc_sphincs_export_private(sphincs_key* key, byte* out, word32* outLen)
+{
+    /* sanity checks on arguments */
+    if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level != 1) && (key->level != 3) && (key->level != 5)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->optim != FAST_VARIANT) && (key->optim != SMALL_VARIANT)) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (*outLen < SPHINCS_LEVEL1_PRV_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL1_PRV_KEY_SIZE;
+        return BUFFER_E;
+    }
+    else if ((key->level == 3) && (*outLen < SPHINCS_LEVEL3_PRV_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL3_PRV_KEY_SIZE;
+        return BUFFER_E;
+    }
+    else if ((key->level == 5) && (*outLen < SPHINCS_LEVEL5_PRV_KEY_SIZE)) {
+        *outLen = SPHINCS_LEVEL5_PRV_KEY_SIZE;
+        return BUFFER_E;
+    }
+
+
+    if (key->level == 1) {
+        *outLen = SPHINCS_LEVEL1_PRV_KEY_SIZE;
+        XMEMCPY(out, key->k, SPHINCS_LEVEL1_PRV_KEY_SIZE);
+        XMEMCPY(out + SPHINCS_LEVEL1_PRV_KEY_SIZE, key->p,
+                SPHINCS_LEVEL1_PUB_KEY_SIZE);
+    }
+    else if (key->level == 3) {
+        *outLen = SPHINCS_LEVEL3_PRV_KEY_SIZE;
+        XMEMCPY(out, key->k, SPHINCS_LEVEL3_PRV_KEY_SIZE);
+        XMEMCPY(out + SPHINCS_LEVEL3_PRV_KEY_SIZE, key->p,
+                SPHINCS_LEVEL3_PUB_KEY_SIZE);
+    }
+    else if (key->level == 5) {
+        *outLen = SPHINCS_LEVEL5_PRV_KEY_SIZE;
+        XMEMCPY(out, key->k, SPHINCS_LEVEL5_PRV_KEY_SIZE);
+        XMEMCPY(out + SPHINCS_LEVEL5_PRV_KEY_SIZE, key->p,
+                SPHINCS_LEVEL5_PUB_KEY_SIZE);
+    }
+
+    return 0;
+}
+
+/* Export the sphincs private and public key.
+ *
+ * key     [in]      Sphincs private/public key.
+ * priv    [in]      Array to hold private key.
+ * privSz  [in/out]  On in, the number of bytes in private key array.
+ * pub     [in]      Array to hold  public key.
+ * pubSz   [in/out]  On in, the number of bytes in public key array.
+ *                   On out, the number bytes put into array.
+ * returns BAD_FUNC_ARG when a parameter is NULL,
+ *         BUFFER_E when privSz is or pubSz is less than required,
+ *         0 otherwise.
+ */
+int wc_sphincs_export_key(sphincs_key* key, byte* priv, word32 *privSz,
+                            byte* pub, word32 *pubSz)
+{
+    int ret = 0;
+
+    /* export private part */
+    ret = wc_sphincs_export_private(key, priv, privSz);
+    if (ret == 0) {
+        /* export public part */
+        ret = wc_sphincs_export_public(key, pub, pubSz);
+    }
+
+    return ret;
+}
+
+/* Check the public key of the sphincs key matches the private key.
+ *
+ * key     [in]      Sphincs private/public key.
+ * returns BAD_FUNC_ARG when key is NULL,
+ *         PUBLIC_KEY_E when the public key is not set or doesn't match,
+ *         other -ve value on hash failure,
+ *         0 otherwise.
+ */
+int wc_sphincs_check_key(sphincs_key* key)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    /* Assume everything is fine. */
+    return 0;
+}
+
+/* Returns the size of a sphincs private key.
+ *
+ * key     [in]      Sphincs private/public key.
+ * returns BAD_FUNC_ARG when key is NULL,
+ *         SPHINCS_LEVELn_KEY_SIZE otherwise.
+ */
+int wc_sphincs_size(sphincs_key* key)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (key->level == 1) {
+        return SPHINCS_LEVEL1_KEY_SIZE;
+    }
+    else if (key->level == 3) {
+        return SPHINCS_LEVEL3_KEY_SIZE;
+    }
+    else if (key->level == 5) {
+        return SPHINCS_LEVEL5_KEY_SIZE;
+    }
+
+    return BAD_FUNC_ARG;
+}
+
+/* Returns the size of a sphincs private plus public key.
+ *
+ * key     [in]      Sphincs private/public key.
+ * returns BAD_FUNC_ARG when key is NULL,
+ *         SPHINCS_LEVELn_PRV_KEY_SIZE otherwise.
+ */
+int wc_sphincs_priv_size(sphincs_key* key)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (key->level == 1) {
+        return SPHINCS_LEVEL1_PRV_KEY_SIZE;
+    }
+    else if (key->level == 3) {
+        return SPHINCS_LEVEL3_PRV_KEY_SIZE;
+    }
+    else if (key->level == 5) {
+        return SPHINCS_LEVEL5_PRV_KEY_SIZE;
+    }
+
+    return BAD_FUNC_ARG;
+}
+
+/* Returns the size of a sphincs public key.
+ *
+ * key     [in]      Sphincs private/public key.
+ * returns BAD_FUNC_ARG when key is NULL,
+ *         SPHINCS_FAST_LEVEL1_PUB_KEY_SIZE otherwise.
+ */
+int wc_sphincs_pub_size(sphincs_key* key)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (key->level == 1) {
+        return SPHINCS_LEVEL1_PUB_KEY_SIZE;
+    }
+    else if (key->level == 3) {
+        return SPHINCS_LEVEL3_PUB_KEY_SIZE;
+    }
+    else if (key->level == 5) {
+        return SPHINCS_LEVEL5_PUB_KEY_SIZE;
+    }
+
+    return BAD_FUNC_ARG;
+}
+
+/* Returns the size of a sphincs signature.
+ *
+ * key     [in]      Sphincs private/public key.
+ * returns BAD_FUNC_ARG when key is NULL,
+ *         SPHINCS_FAST_LEVEL1_SIG_SIZE otherwise.
+ */
+int wc_sphincs_sig_size(sphincs_key* key)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (key->optim == FAST_VARIANT)) {
+        return SPHINCS_FAST_LEVEL1_SIG_SIZE;
+    }
+    else if ((key->level == 3) && (key->optim == FAST_VARIANT)) {
+        return SPHINCS_FAST_LEVEL3_SIG_SIZE;
+    }
+    else if ((key->level == 5) && (key->optim == FAST_VARIANT)) {
+        return SPHINCS_FAST_LEVEL5_SIG_SIZE;
+    }
+    else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) {
+        return SPHINCS_SMALL_LEVEL1_SIG_SIZE;
+    }
+    else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) {
+        return SPHINCS_SMALL_LEVEL3_SIG_SIZE;
+    }
+    else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) {
+        return SPHINCS_SMALL_LEVEL5_SIG_SIZE;
+    }
+
+    return BAD_FUNC_ARG;
+}
+
+int wc_Sphincs_PrivateKeyDecode(const byte* input, word32* inOutIdx,
+                                sphincs_key* key, word32 inSz)
+{
+    int ret = 0;
+    byte privKey[SPHINCS_MAX_KEY_SIZE], pubKey[SPHINCS_MAX_PUB_KEY_SIZE];
+    word32 privKeyLen = (word32)sizeof(privKey);
+    word32 pubKeyLen = (word32)sizeof(pubKey);
+    int keytype = 0;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL1k;
+    }
+    else if ((key->level == 3) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL3k;
+    }
+    else if ((key->level == 5) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL5k;
+    }
+    if ((key->level == 1) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL1k;
+    }
+    else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL3k;
+    }
+    else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL5k;
+    }
+    else {
+        return BAD_FUNC_ARG;
+    }
+
+    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
+                        pubKey, &pubKeyLen, keytype);
+    if (ret == 0) {
+        if (pubKeyLen == 0) {
+            ret = wc_sphincs_import_private_only(input, inSz, key);
+        }
+        else {
+            ret = wc_sphincs_import_private_key(privKey, privKeyLen,
+                                               pubKey, pubKeyLen, key);
+        }
+    }
+    return ret;
+}
+
+int wc_Sphincs_PublicKeyDecode(const byte* input, word32* inOutIdx,
+                               sphincs_key* key, word32 inSz)
+{
+    int ret = 0;
+    byte pubKey[SPHINCS_MAX_PUB_KEY_SIZE];
+    word32 pubKeyLen = (word32)sizeof(pubKey);
+    int keytype = 0;
+
+    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL1k;
+    }
+    else if ((key->level == 3) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL3k;
+    }
+    else if ((key->level == 5) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL5k;
+    }
+    if ((key->level == 1) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL1k;
+    }
+    else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL3k;
+    }
+    else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL5k;
+    }
+    else {
+        return BAD_FUNC_ARG;
+    }
+
+    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen,
+                              keytype);
+    if (ret == 0) {
+        ret = wc_sphincs_import_public(pubKey, pubKeyLen, key);
+    }
+    return ret;
+}
+
+#ifdef WC_ENABLE_ASYM_KEY_EXPORT
+/* Encode the public part of an Sphincs key in DER.
+ *
+ * Pass NULL for output to get the size of the encoding.
+ *
+ * @param [in]  key       Sphincs key object.
+ * @param [out] output    Buffer to put encoded data in.
+ * @param [in]  outLen    Size of buffer in bytes.
+ * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
+ * @return  Size of encoded data in bytes on success.
+ * @return  BAD_FUNC_ARG when key is NULL.
+ * @return  MEMORY_E when dynamic memory allocation failed.
+ */
+int wc_Sphincs_PublicKeyToDer(sphincs_key* key, byte* output, word32 inLen,
+                              int withAlg)
+{
+    int    ret;
+    byte   pubKey[SPHINCS_MAX_PUB_KEY_SIZE];
+    word32 pubKeyLen = (word32)sizeof(pubKey);
+    int    keytype = 0;
+
+    if (key == NULL || output == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL1k;
+    }
+    else if ((key->level == 3) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL3k;
+    }
+    else if ((key->level == 5) && (key->optim == FAST_VARIANT)) {
+        keytype = SPHINCS_FAST_LEVEL5k;
+    }
+    if ((key->level == 1) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL1k;
+    }
+    else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL3k;
+    }
+    else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) {
+        keytype = SPHINCS_SMALL_LEVEL5k;
+    }
+    else {
+        return BAD_FUNC_ARG;
+    }
+
+    ret = wc_sphincs_export_public(key, pubKey, &pubKeyLen);
+    if (ret == 0) {
+        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen, keytype,
+                                  withAlg);
+    }
+
+    return ret;
+}
+#endif
+
+int wc_Sphincs_KeyToDer(sphincs_key* key, byte* output, word32 inLen)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (key->optim == FAST_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, key->p,
+                             SPHINCS_LEVEL1_KEY_SIZE, output, inLen,
+                             SPHINCS_FAST_LEVEL1k);
+    }
+    else if ((key->level == 3) && (key->optim == FAST_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, key->p,
+                             SPHINCS_LEVEL3_KEY_SIZE, output, inLen,
+                             SPHINCS_FAST_LEVEL3k);
+    }
+    else if ((key->level == 5) && (key->optim == FAST_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, key->p,
+                             SPHINCS_LEVEL5_KEY_SIZE, output, inLen,
+                             SPHINCS_FAST_LEVEL5k);
+    }
+    else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, key->p,
+                             SPHINCS_LEVEL1_KEY_SIZE, output, inLen,
+                             SPHINCS_SMALL_LEVEL1k);
+    }
+    else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, key->p,
+                             SPHINCS_LEVEL3_KEY_SIZE, output, inLen,
+                             SPHINCS_SMALL_LEVEL3k);
+    }
+    else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, key->p,
+                             SPHINCS_LEVEL5_KEY_SIZE, output, inLen,
+                             SPHINCS_SMALL_LEVEL5k);
+    }
+
+    return BAD_FUNC_ARG;
+}
+
+int wc_Sphincs_PrivateKeyToDer(sphincs_key* key, byte* output, word32 inLen)
+{
+    if (key == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if ((key->level == 1) && (key->optim == FAST_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, NULL, 0, output,
+                             inLen, SPHINCS_FAST_LEVEL1k);
+    }
+    else if ((key->level == 3) && (key->optim == FAST_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, NULL, 0, output,
+                             inLen, SPHINCS_FAST_LEVEL3k);
+    }
+    else if ((key->level == 5) && (key->optim == FAST_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, NULL, 0, output,
+                             inLen, SPHINCS_FAST_LEVEL5k);
+    }
+    else if ((key->level == 1) && (key->optim == SMALL_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL1_KEY_SIZE, NULL, 0, output,
+                             inLen, SPHINCS_SMALL_LEVEL1k);
+    }
+    else if ((key->level == 3) && (key->optim == SMALL_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL3_KEY_SIZE, NULL, 0, output,
+                             inLen, SPHINCS_SMALL_LEVEL3k);
+    }
+    else if ((key->level == 5) && (key->optim == SMALL_VARIANT)) {
+        return SetAsymKeyDer(key->k, SPHINCS_LEVEL5_KEY_SIZE, NULL, 0, output,
+                             inLen, SPHINCS_SMALL_LEVEL5k);
+    }
+
+    return BAD_FUNC_ARG;
+}
+#endif /* HAVE_PQC && HAVE_SPHINCS */
diff --git a/wolfssl/certs_test.h b/wolfssl/certs_test.h
index 77e6ee584..12372968b 100644
--- a/wolfssl/certs_test.h
+++ b/wolfssl/certs_test.h
@@ -3349,7 +3349,7 @@ static const int sizeof_dh_key_der_4096 = sizeof(dh_key_der_4096);
 
 #endif /* USE_CERT_BUFFERS_4096 */
 
-#ifdef HAVE_PQC
+#if defined(HAVE_PQC) && defined(HAVE_FALCON)
 
 /* certs/falcon/bench_falcon_level1_key.der */
 static const unsigned char bench_falcon_level1_key[] =
@@ -3997,9 +3997,9 @@ static const unsigned char bench_falcon_level5_key[] =
 };
 static const int sizeof_bench_falcon_level5_key = sizeof(bench_falcon_level5_key);
 
-#endif /* HAVE_PQC */
+#endif /* HAVE_PQC && HAVE_FALCON */
 
-#ifdef HAVE_PQC
+#if defined (HAVE_PQC) && defined(HAVE_DILITHIUM)
 
 /* certs/dilithium/bench_dilithium_level2_key.der */
 static const unsigned char bench_dilithium_level2_key[] =
@@ -7509,7 +7509,149 @@ static const unsigned char bench_dilithium_aes_level5_key[] =
 };
 static const int sizeof_bench_dilithium_aes_level5_key = sizeof(bench_dilithium_aes_level5_key);
 
-#endif /* HAVE_PQC */
+#endif /* HAVE_PQC && HAVE_DILITHIUM */
+
+#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
+
+/* certs/sphincs/bench_sphincs_fast_level1_key.der */
+static const unsigned char bench_sphincs_fast_level1_key[] =
+{
+        0x30, 0x71, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, 0x2B,
+        0xCE, 0x0F, 0x06, 0x07, 0x04, 0x04, 0x62, 0x04, 0x60, 0x59,
+        0xE0, 0xD4, 0x1F, 0x22, 0x74, 0xBD, 0xAC, 0x46, 0x01, 0xE4,
+        0x8C, 0x89, 0xB7, 0x39, 0x20, 0x9F, 0x6F, 0x96, 0xC4, 0xE7,
+        0x78, 0x0F, 0xA1, 0x7D, 0xEC, 0xE8, 0xD5, 0xC3, 0xDD, 0x45,
+        0x13, 0x56, 0xCF, 0xEA, 0x68, 0x70, 0x2A, 0xFF, 0xDA, 0x9A,
+        0xA3, 0x2B, 0xEC, 0x4D, 0xBF, 0x7D, 0x09, 0xC0, 0xCC, 0xF4,
+        0x2F, 0xF2, 0xAC, 0x74, 0xDF, 0x0E, 0x20, 0x9D, 0xC2, 0x9E,
+        0xD1, 0xB4, 0x12, 0x56, 0xCF, 0xEA, 0x68, 0x70, 0x2A, 0xFF,
+        0xDA, 0x9A, 0xA3, 0x2B, 0xEC, 0x4D, 0xBF, 0x7D, 0x09, 0xC0,
+        0xCC, 0xF4, 0x2F, 0xF2, 0xAC, 0x74, 0xDF, 0x0E, 0x20, 0x9D,
+        0xC2, 0x9E, 0xD1, 0xB4, 0x12
+};
+static const int sizeof_bench_sphincs_fast_level1_key = sizeof(bench_sphincs_fast_level1_key);
+
+/* certs/sphincs/bench_sphincs_fast_level3_key.der */
+static const unsigned char bench_sphincs_fast_level3_key[] =
+{
+        0x30, 0x81, 0xA3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06,
+        0x2B, 0xCE, 0x0F, 0x06, 0x08, 0x03, 0x04, 0x81, 0x93, 0x04,
+        0x81, 0x90, 0x00, 0x8E, 0xB0, 0x75, 0x2E, 0xC5, 0x61, 0x66,
+        0xEE, 0x01, 0xEE, 0x97, 0x13, 0xD7, 0x65, 0x69, 0xEA, 0x5C,
+        0x23, 0xAA, 0x6E, 0x86, 0x04, 0xE9, 0x2A, 0xEC, 0x8C, 0xA3,
+        0xB7, 0x28, 0xEB, 0xDF, 0x0E, 0x77, 0x07, 0x59, 0x3F, 0xB6,
+        0x10, 0xB3, 0xCC, 0xE1, 0x09, 0x64, 0xC4, 0x42, 0x37, 0x71,
+        0xDC, 0xB4, 0x20, 0x2D, 0x03, 0x00, 0x6C, 0x4C, 0x3F, 0xE3,
+        0x80, 0x28, 0xEC, 0x90, 0xF9, 0xDB, 0x50, 0xFC, 0x0A, 0x58,
+        0xC2, 0x81, 0xE2, 0x17, 0x06, 0x7A, 0x58, 0xBB, 0x21, 0x90,
+        0xC8, 0xE6, 0x64, 0x8B, 0xF4, 0x68, 0x70, 0x1D, 0xE2, 0xAB,
+        0x8F, 0x50, 0x4D, 0xEE, 0x29, 0xD7, 0x15, 0x5E, 0xDC, 0xB4,
+        0x20, 0x2D, 0x03, 0x00, 0x6C, 0x4C, 0x3F, 0xE3, 0x80, 0x28,
+        0xEC, 0x90, 0xF9, 0xDB, 0x50, 0xFC, 0x0A, 0x58, 0xC2, 0x81,
+        0xE2, 0x17, 0x06, 0x7A, 0x58, 0xBB, 0x21, 0x90, 0xC8, 0xE6,
+        0x64, 0x8B, 0xF4, 0x68, 0x70, 0x1D, 0xE2, 0xAB, 0x8F, 0x50,
+        0x4D, 0xEE, 0x29, 0xD7, 0x15, 0x5E
+};
+static const int sizeof_bench_sphincs_fast_level3_key = sizeof(bench_sphincs_fast_level3_key);
+
+/* certs/sphincs/bench_sphincs_fast_level5_key.der */
+static const unsigned char bench_sphincs_fast_level5_key[] =
+{
+        0x30, 0x81, 0xD3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06,
+        0x2B, 0xCE, 0x0F, 0x06, 0x09, 0x03, 0x04, 0x81, 0xC3, 0x04,
+        0x81, 0xC0, 0x91, 0x8B, 0xB7, 0x1A, 0x08, 0x61, 0x50, 0x70,
+        0x26, 0x71, 0xCD, 0x36, 0x10, 0xE2, 0xB8, 0x95, 0x0D, 0xA7,
+        0x57, 0xC7, 0x18, 0xFF, 0x55, 0xA4, 0x16, 0x9D, 0x3C, 0xF8,
+        0xA3, 0x48, 0xB0, 0x9B, 0xFD, 0x22, 0xBE, 0x20, 0x3D, 0x88,
+        0x96, 0x0B, 0xF1, 0x6D, 0x05, 0x8A, 0x1B, 0x71, 0xCE, 0xCD,
+        0x31, 0x01, 0xEA, 0xAC, 0x62, 0x61, 0x1F, 0x4A, 0xC1, 0x62,
+        0x05, 0x36, 0xBB, 0x7F, 0xEF, 0x5B, 0x42, 0x8B, 0xC6, 0xCD,
+        0xEF, 0xCE, 0xE1, 0x00, 0x39, 0x4F, 0x01, 0xBC, 0x03, 0x94,
+        0x00, 0xA8, 0x7F, 0x22, 0xB9, 0x9F, 0x79, 0x51, 0x25, 0x61,
+        0x1B, 0x43, 0x47, 0x52, 0xD0, 0x39, 0x2B, 0x93, 0xC5, 0xD4,
+        0x2A, 0xE1, 0xEF, 0x0B, 0x01, 0x36, 0xC3, 0x54, 0xC8, 0xDE,
+        0xF4, 0xA2, 0x6F, 0x4C, 0x4B, 0xEC, 0x5D, 0x9D, 0xEE, 0xC9,
+        0xFA, 0xBE, 0xFA, 0x5F, 0xC4, 0x89, 0xC1, 0xFC, 0xEB, 0xA8,
+        0x42, 0x8B, 0xC6, 0xCD, 0xEF, 0xCE, 0xE1, 0x00, 0x39, 0x4F,
+        0x01, 0xBC, 0x03, 0x94, 0x00, 0xA8, 0x7F, 0x22, 0xB9, 0x9F,
+        0x79, 0x51, 0x25, 0x61, 0x1B, 0x43, 0x47, 0x52, 0xD0, 0x39,
+        0x2B, 0x93, 0xC5, 0xD4, 0x2A, 0xE1, 0xEF, 0x0B, 0x01, 0x36,
+        0xC3, 0x54, 0xC8, 0xDE, 0xF4, 0xA2, 0x6F, 0x4C, 0x4B, 0xEC,
+        0x5D, 0x9D, 0xEE, 0xC9, 0xFA, 0xBE, 0xFA, 0x5F, 0xC4, 0x89,
+        0xC1, 0xFC, 0xEB, 0xA8
+};
+static const int sizeof_bench_sphincs_fast_level5_key = sizeof(bench_sphincs_fast_level5_key);
+
+/* certs/sphincs/bench_sphincs_small_level1_key.der */
+static const unsigned char bench_sphincs_small_level1_key[] =
+{
+        0x30, 0x71, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06, 0x2B,
+        0xCE, 0x0F, 0x06, 0x07, 0x0A, 0x04, 0x62, 0x04, 0x60, 0x44,
+        0x7A, 0xCF, 0xB9, 0x03, 0xF2, 0xB2, 0x41, 0xBC, 0x1A, 0xE6,
+        0x75, 0x29, 0x04, 0xDA, 0x6C, 0x6E, 0x08, 0x17, 0x1E, 0x46,
+        0x75, 0xE8, 0x32, 0x23, 0xCD, 0x11, 0xC8, 0x88, 0xF7, 0x00,
+        0x11, 0x4C, 0xBD, 0x14, 0x62, 0xC2, 0x4B, 0x83, 0x36, 0xDE,
+        0x61, 0x78, 0x7F, 0x09, 0x16, 0x97, 0x98, 0x3D, 0x52, 0x70,
+        0x7F, 0xED, 0x86, 0xDB, 0x75, 0x42, 0x52, 0xF3, 0xB1, 0xAE,
+        0x70, 0x7F, 0xD3, 0x4C, 0xBD, 0x14, 0x62, 0xC2, 0x4B, 0x83,
+        0x36, 0xDE, 0x61, 0x78, 0x7F, 0x09, 0x16, 0x97, 0x98, 0x3D,
+        0x52, 0x70, 0x7F, 0xED, 0x86, 0xDB, 0x75, 0x42, 0x52, 0xF3,
+        0xB1, 0xAE, 0x70, 0x7F, 0xD3
+};
+static const int sizeof_bench_sphincs_small_level1_key = sizeof(bench_sphincs_small_level1_key);
+
+/* certs/sphincs/bench_sphincs_small_level3_key.der */
+static const unsigned char bench_sphincs_small_level3_key[] =
+{
+        0x30, 0x81, 0xA3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06,
+        0x2B, 0xCE, 0x0F, 0x06, 0x08, 0x07, 0x04, 0x81, 0x93, 0x04,
+        0x81, 0x90, 0x7E, 0x80, 0x20, 0x6C, 0x20, 0xAE, 0x7D, 0xAB,
+        0xC1, 0x4E, 0x15, 0x51, 0x0C, 0xDD, 0x96, 0xAC, 0xFB, 0xD2,
+        0x5B, 0xF1, 0xEB, 0x51, 0xDC, 0xC3, 0xB3, 0x92, 0x33, 0xC2,
+        0x54, 0x59, 0x4F, 0xB2, 0x33, 0x7C, 0x10, 0xC6, 0xA3, 0x49,
+        0x8D, 0x07, 0x52, 0xB2, 0xA1, 0x14, 0x0C, 0x54, 0x21, 0xD4,
+        0xB1, 0xCC, 0xBD, 0xB1, 0x20, 0xAC, 0xF1, 0xBD, 0xF5, 0x60,
+        0x2F, 0x07, 0x98, 0x57, 0x4E, 0x31, 0x6F, 0x42, 0x84, 0xCE,
+        0x71, 0x72, 0x74, 0x20, 0xDF, 0x38, 0x39, 0xFB, 0xD3, 0xEE,
+        0xAD, 0xFB, 0xB6, 0x2B, 0x60, 0x61, 0x85, 0xF1, 0x2A, 0x59,
+        0x00, 0xA5, 0xCA, 0xC8, 0xE3, 0x3F, 0x96, 0xE9, 0xB1, 0xCC,
+        0xBD, 0xB1, 0x20, 0xAC, 0xF1, 0xBD, 0xF5, 0x60, 0x2F, 0x07,
+        0x98, 0x57, 0x4E, 0x31, 0x6F, 0x42, 0x84, 0xCE, 0x71, 0x72,
+        0x74, 0x20, 0xDF, 0x38, 0x39, 0xFB, 0xD3, 0xEE, 0xAD, 0xFB,
+        0xB6, 0x2B, 0x60, 0x61, 0x85, 0xF1, 0x2A, 0x59, 0x00, 0xA5,
+        0xCA, 0xC8, 0xE3, 0x3F, 0x96, 0xE9
+};
+static const int sizeof_bench_sphincs_small_level3_key = sizeof(bench_sphincs_small_level3_key);
+
+/* certs/sphincs/bench_sphincs_small_level5_key.der */
+static const unsigned char bench_sphincs_small_level5_key[] =
+{
+        0x30, 0x81, 0xD3, 0x02, 0x01, 0x00, 0x30, 0x08, 0x06, 0x06,
+        0x2B, 0xCE, 0x0F, 0x06, 0x09, 0x07, 0x04, 0x81, 0xC3, 0x04,
+        0x81, 0xC0, 0x5E, 0xEA, 0x46, 0x6D, 0xE5, 0xA1, 0x70, 0x07,
+        0xF0, 0x5C, 0x59, 0xD5, 0xD7, 0x37, 0x06, 0xC7, 0xD6, 0x1C,
+        0xEA, 0x06, 0x15, 0x6E, 0xB3, 0x07, 0x71, 0x34, 0xE8, 0xD4,
+        0x13, 0x65, 0x58, 0xAE, 0xAC, 0xE9, 0x32, 0x26, 0x76, 0xCD,
+        0x2C, 0x3D, 0x11, 0xF7, 0xAB, 0x8A, 0x84, 0x4F, 0x56, 0x6F,
+        0x2F, 0x63, 0x82, 0x1A, 0x37, 0xAA, 0xAA, 0x49, 0x50, 0xC8,
+        0xA5, 0x92, 0x6E, 0x3F, 0xD6, 0x67, 0xEA, 0x5C, 0x18, 0x8A,
+        0x99, 0xD2, 0xB6, 0xE3, 0xD7, 0x68, 0x9E, 0x65, 0x21, 0xDD,
+        0xE3, 0x44, 0x8B, 0x32, 0x30, 0x31, 0xA8, 0xF2, 0xBB, 0xED,
+        0xC0, 0x3E, 0x1A, 0x7B, 0x36, 0xD8, 0xAD, 0x2A, 0xA4, 0x81,
+        0xAC, 0xD3, 0x08, 0xAC, 0x54, 0x2A, 0xAC, 0xAA, 0x1B, 0x64,
+        0x58, 0x7B, 0x94, 0xE0, 0x16, 0x36, 0xC9, 0x92, 0x09, 0x6A,
+        0x8C, 0x4D, 0xE3, 0xAB, 0x0F, 0x1C, 0xE8, 0x77, 0x1F, 0xE5,
+        0xEA, 0x5C, 0x18, 0x8A, 0x99, 0xD2, 0xB6, 0xE3, 0xD7, 0x68,
+        0x9E, 0x65, 0x21, 0xDD, 0xE3, 0x44, 0x8B, 0x32, 0x30, 0x31,
+        0xA8, 0xF2, 0xBB, 0xED, 0xC0, 0x3E, 0x1A, 0x7B, 0x36, 0xD8,
+        0xAD, 0x2A, 0xA4, 0x81, 0xAC, 0xD3, 0x08, 0xAC, 0x54, 0x2A,
+        0xAC, 0xAA, 0x1B, 0x64, 0x58, 0x7B, 0x94, 0xE0, 0x16, 0x36,
+        0xC9, 0x92, 0x09, 0x6A, 0x8C, 0x4D, 0xE3, 0xAB, 0x0F, 0x1C,
+        0xE8, 0x77, 0x1F, 0xE5
+};
+static const int sizeof_bench_sphincs_small_level5_key = sizeof(bench_sphincs_small_level5_key);
+
+#endif /* HAVE_PQC && HAVE_SPHINCS */
 
 #if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
 
diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h
index 902113759..72267f50c 100644
--- a/wolfssl/wolfcrypt/asn.h
+++ b/wolfssl/wolfcrypt/asn.h
@@ -1095,6 +1095,12 @@ enum Key_Sum {
     DILITHIUM_AES_LEVEL2k = 217,/* 1.3.6.1.4.1.2.267.11.4.4 */
     DILITHIUM_AES_LEVEL3k = 221,/* 1.3.6.1.4.1.2.267.11.6.5 + 1 (See GetOID() in asn.c) */
     DILITHIUM_AES_LEVEL5k = 224,/* 1.3.6.1.4.1.2.267.11.8.7 */
+    SPHINCS_FAST_LEVEL1k   = 281, /* 1 3 9999 6 7 4 */
+    SPHINCS_FAST_LEVEL3k   = 283, /* 1 3 9999 6 8 3 + 2 (See GetOID() in asn.c) */
+    SPHINCS_FAST_LEVEL5k   = 282, /* 1 3 9999 6 9 3 */
+    SPHINCS_SMALL_LEVEL1k  = 287, /* 1 3 9999 6 7 10 */
+    SPHINCS_SMALL_LEVEL3k  = 285, /* 1 3 9999 6 8 7 */
+    SPHINCS_SMALL_LEVEL5k  = 286, /* 1 3 9999 6 9 7 */
 };
 
 #if !defined(NO_AES) || defined(HAVE_PKCS7)
@@ -1411,6 +1417,7 @@ struct SignatureCtx {
     #ifdef HAVE_PQC
         struct falcon_key* falcon;
         struct dilithium_key* dilithium;
+        struct sphincs_key* sphincs;
     #endif
         void* ptr;
     } key;
@@ -2233,6 +2240,12 @@ enum cert_enums {
     DILITHIUM_AES_LEVEL2_KEY = 21,
     DILITHIUM_AES_LEVEL3_KEY = 22,
     DILITHIUM_AES_LEVEL5_KEY = 23,
+    SPHINCS_FAST_LEVEL1_KEY  = 24,
+    SPHINCS_FAST_LEVEL3_KEY  = 25,
+    SPHINCS_FAST_LEVEL5_KEY  = 26,
+    SPHINCS_SMALL_LEVEL1_KEY = 27,
+    SPHINCS_SMALL_LEVEL3_KEY = 28,
+    SPHINCS_SMALL_LEVEL5_KEY = 29,
 };
 
 #endif /* WOLFSSL_CERT_GEN */
@@ -2473,7 +2486,8 @@ WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL* dcrl);
     || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \
     || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
     || (defined(HAVE_PQC) && defined(HAVE_FALCON)) \
-    || (defined(HAVE_PQC) && defined(HAVE_DILITHIUM)))
+    || (defined(HAVE_PQC) && defined(HAVE_DILITHIUM)) \
+    || (defined(HAVE_PQC) && defined(HAVE_SPHINCS)))
 WOLFSSL_LOCAL int DecodeAsymKey(const byte* input, word32* inOutIdx,
     word32 inSz, byte* privKey, word32* privKeyLen, byte* pubKey,
     word32* pubKeyLen, int keyType);
diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h
index dcfb00499..0f212b5fd 100644
--- a/wolfssl/wolfcrypt/asn_public.h
+++ b/wolfssl/wolfcrypt/asn_public.h
@@ -76,6 +76,10 @@ This library defines the interface APIs for X509 certificates.
     typedef struct dilithium_key dilithium_key;
     #define WC_DILITHIUMKEY_TYPE_DEFINED
 #endif
+#ifndef WC_SPHINCSKEY_TYPE_DEFINED
+    typedef struct sphincs_key sphincs_key;
+    #define WC_SPHINCSKEY_TYPE_DEFINED
+#endif
 
 enum Ecc_Sum {
     ECC_SECP112R1_OID = 182,
@@ -147,6 +151,13 @@ enum CertType {
     DILITHIUM_AES_LEVEL2_TYPE,
     DILITHIUM_AES_LEVEL3_TYPE,
     DILITHIUM_AES_LEVEL5_TYPE,
+    SPHINCS_FAST_LEVEL1_TYPE,
+    SPHINCS_FAST_LEVEL3_TYPE,
+    SPHINCS_FAST_LEVEL5_TYPE,
+    SPHINCS_SMALL_LEVEL1_TYPE,
+    SPHINCS_SMALL_LEVEL3_TYPE,
+    SPHINCS_SMALL_LEVEL5_TYPE,
+
 };
 
 
@@ -191,6 +202,13 @@ enum Ctc_SigType {
     CTC_DILITHIUM_AES_LEVEL2 = 217,
     CTC_DILITHIUM_AES_LEVEL3 = 221,
     CTC_DILITHIUM_AES_LEVEL5 = 224,
+
+    CTC_SPHINCS_FAST_LEVEL1  = 281,
+    CTC_SPHINCS_FAST_LEVEL3  = 283,
+    CTC_SPHINCS_FAST_LEVEL5  = 282,
+    CTC_SPHINCS_SMALL_LEVEL1 = 287,
+    CTC_SPHINCS_SMALL_LEVEL3 = 285,
+    CTC_SPHINCS_SMALL_LEVEL5 = 286,
 };
 
 enum Ctc_Encoding {
@@ -725,7 +743,8 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
      (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)) || \
      (defined(HAVE_ED448)      && defined(HAVE_ED448_KEY_EXPORT)) || \
      (defined(HAVE_CURVE448)   && defined(HAVE_CURVE448_KEY_EXPORT)) || \
-     (defined(HAVE_PQC) && (defined(HAVE_FALCON) || defined(HAVE_DILITHIUM))))
+     (defined(HAVE_PQC) && (defined(HAVE_FALCON) || \
+                            defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS))))
     #define WC_ENABLE_ASYM_KEY_EXPORT
 #endif
 
@@ -786,32 +805,6 @@ WOLFSSL_API int wc_Ed448PublicKeyToDer(
 #endif
 #endif /* HAVE_ED448 */
 
-#ifdef HAVE_PQC
-WOLFSSL_API int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx,
-                                           falcon_key* key, word32 inSz);
-WOLFSSL_API int wc_Falcon_PublicKeyDecode(const byte* input, word32* inOutIdx,
-                                          falcon_key* key, word32 inSz);
-WOLFSSL_API int wc_Falcon_KeyToDer(falcon_key* key, byte* output,
-                                   word32 inLen);
-WOLFSSL_API int wc_Falcon_PrivateKeyToDer(falcon_key* key, byte* output,
-                                          word32 inLen);
-WOLFSSL_API int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output,
-                                         word32 inLen, int withAlg);
-
-WOLFSSL_API int wc_Dilithium_PrivateKeyDecode(const byte* input,
-                                              word32* inOutIdx,
-                                              dilithium_key* key, word32 inSz);
-WOLFSSL_API int wc_Dilithium_PublicKeyDecode(const byte* input,
-                                             word32* inOutIdx,
-                                             dilithium_key* key, word32 inSz);
-WOLFSSL_API int wc_Dilithium_KeyToDer(dilithium_key* key, byte* output,
-                                      word32 inLen);
-WOLFSSL_API int wc_Dilithium_PrivateKeyToDer(dilithium_key* key, byte* output,
-                                             word32 inLen);
-WOLFSSL_API int wc_Dilithium_PublicKeyToDer(dilithium_key* key, byte* output,
-                                            word32 inLen, int withAlg);
-#endif /* HAVE_PQC */
-
 #ifdef HAVE_CURVE448
 #ifdef HAVE_CURVE448_KEY_IMPORT
 WOLFSSL_API int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
diff --git a/wolfssl/wolfcrypt/dilithium.h b/wolfssl/wolfcrypt/dilithium.h
index 8199c038d..316fae10c 100644
--- a/wolfssl/wolfcrypt/dilithium.h
+++ b/wolfssl/wolfcrypt/dilithium.h
@@ -134,6 +134,19 @@ int wc_dilithium_pub_size(dilithium_key* key);
 WOLFSSL_API
 int wc_dilithium_sig_size(dilithium_key* key);
 
+WOLFSSL_API int wc_Dilithium_PrivateKeyDecode(const byte* input,
+                                              word32* inOutIdx,
+                                              dilithium_key* key, word32 inSz);
+WOLFSSL_API int wc_Dilithium_PublicKeyDecode(const byte* input,
+                                             word32* inOutIdx,
+                                             dilithium_key* key, word32 inSz);
+WOLFSSL_API int wc_Dilithium_KeyToDer(dilithium_key* key, byte* output,
+                                      word32 inLen);
+WOLFSSL_API int wc_Dilithium_PrivateKeyToDer(dilithium_key* key, byte* output,
+                                             word32 inLen);
+WOLFSSL_API int wc_Dilithium_PublicKeyToDer(dilithium_key* key, byte* output,
+                                            word32 inLen, int withAlg);
+
 #ifdef __cplusplus
     }    /* extern "C" */
 #endif
diff --git a/wolfssl/wolfcrypt/falcon.h b/wolfssl/wolfcrypt/falcon.h
index 7f6116727..d4f0b352c 100644
--- a/wolfssl/wolfcrypt/falcon.h
+++ b/wolfssl/wolfcrypt/falcon.h
@@ -125,6 +125,17 @@ int wc_falcon_pub_size(falcon_key* key);
 WOLFSSL_API
 int wc_falcon_sig_size(falcon_key* key);
 
+WOLFSSL_API int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx,
+                                           falcon_key* key, word32 inSz);
+WOLFSSL_API int wc_Falcon_PublicKeyDecode(const byte* input, word32* inOutIdx,
+                                          falcon_key* key, word32 inSz);
+WOLFSSL_API int wc_Falcon_KeyToDer(falcon_key* key, byte* output,
+                                   word32 inLen);
+WOLFSSL_API int wc_Falcon_PrivateKeyToDer(falcon_key* key, byte* output,
+                                          word32 inLen);
+WOLFSSL_API int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output,
+                                         word32 inLen, int withAlg);
+
 #ifdef __cplusplus
     }    /* extern "C" */
 #endif
diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am
index 9aea5a654..c68d784bc 100644
--- a/wolfssl/wolfcrypt/include.am
+++ b/wolfssl/wolfcrypt/include.am
@@ -23,6 +23,7 @@ nobase_include_HEADERS+= \
                          wolfssl/wolfcrypt/ed448.h \
                          wolfssl/wolfcrypt/falcon.h \
                          wolfssl/wolfcrypt/dilithium.h \
+                         wolfssl/wolfcrypt/sphincs.h \
                          wolfssl/wolfcrypt/fe_448.h \
                          wolfssl/wolfcrypt/ge_448.h \
                          wolfssl/wolfcrypt/eccsi.h \
diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h
index b79f27021..e23cd433b 100644
--- a/wolfssl/wolfcrypt/settings.h
+++ b/wolfssl/wolfcrypt/settings.h
@@ -2721,6 +2721,7 @@ extern void uITRON4_free(void *p) ;
 #define HAVE_PQC
 #define HAVE_FALCON
 #define HAVE_DILITHIUM
+#define HAVE_SPHINCS
 #define HAVE_KYBER
 #endif
 
diff --git a/wolfssl/wolfcrypt/sphincs.h b/wolfssl/wolfcrypt/sphincs.h
new file mode 100644
index 000000000..a927a2234
--- /dev/null
+++ b/wolfssl/wolfcrypt/sphincs.h
@@ -0,0 +1,166 @@
+/* sphincs.h
+ *
+ * Copyright (C) 2022 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+/*!
+    \file wolfssl/wolfcrypt/sphincs.h
+*/
+
+/* Interfaces for Sphincs:
+ *     - SPHINCS_FAST_LEVEL1 (AKA SPHINCS+-SHAKE256-128f-simple)
+ *     - SPHINCS_FAST_LEVEL3 (AKA SPHINCS+-SHAKE256-192f-simple)
+ *     - SPHINCS_FAST_LEVEL5 (AKA SPHINCS+-SHAKE256-256f-simple)
+ *     - SPHINCS_SMALL_LEVEL1 (AKA SPHINCS+-SHAKE256-128s-simple)
+ *     - SPHINCS_SMALL_LEVEL3 (AKA SPHINCS+-SHAKE256-192s-simple)
+ *     - SPHINCS_SMALL_LEVEL5 (AKA SPHINCS+-SHAKE256-256s-simple)
+ */
+
+#ifndef WOLF_CRYPT_SPHINCS_H
+#define WOLF_CRYPT_SPHINCS_H
+
+#include <wolfssl/wolfcrypt/types.h>
+
+#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
+
+#ifdef HAVE_LIBOQS
+#include <oqs/oqs.h>
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/* Macros Definitions */
+
+#ifdef HAVE_LIBOQS
+
+#define SPHINCS_FAST_LEVEL1_SIG_SIZE     OQS_SIG_sphincs_shake256_128f_simple_length_signature
+#define SPHINCS_FAST_LEVEL3_SIG_SIZE     OQS_SIG_sphincs_shake256_192f_simple_length_signature
+#define SPHINCS_FAST_LEVEL5_SIG_SIZE     OQS_SIG_sphincs_shake256_256f_simple_length_signature
+#define SPHINCS_SMALL_LEVEL1_SIG_SIZE    OQS_SIG_sphincs_shake256_128s_simple_length_signature
+#define SPHINCS_SMALL_LEVEL3_SIG_SIZE    OQS_SIG_sphincs_shake256_192s_simple_length_signature
+#define SPHINCS_SMALL_LEVEL5_SIG_SIZE    OQS_SIG_sphincs_shake256_256s_simple_length_signature
+
+#define SPHINCS_LEVEL1_KEY_SIZE     OQS_SIG_sphincs_shake256_128f_simple_length_secret_key
+#define SPHINCS_LEVEL1_PUB_KEY_SIZE OQS_SIG_sphincs_shake256_128f_simple_length_public_key
+#define SPHINCS_LEVEL1_PRV_KEY_SIZE (SPHINCS_LEVEL1_PUB_KEY_SIZE+SPHINCS_LEVEL1_KEY_SIZE)
+
+#define SPHINCS_LEVEL3_KEY_SIZE     OQS_SIG_sphincs_shake256_192f_simple_length_secret_key
+#define SPHINCS_LEVEL3_PUB_KEY_SIZE OQS_SIG_sphincs_shake256_192f_simple_length_public_key
+#define SPHINCS_LEVEL3_PRV_KEY_SIZE (SPHINCS_LEVEL3_PUB_KEY_SIZE+SPHINCS_LEVEL3_KEY_SIZE)
+
+#define SPHINCS_LEVEL5_KEY_SIZE     OQS_SIG_sphincs_shake256_256f_simple_length_secret_key
+#define SPHINCS_LEVEL5_PUB_KEY_SIZE OQS_SIG_sphincs_shake256_256f_simple_length_public_key
+#define SPHINCS_LEVEL5_PRV_KEY_SIZE (SPHINCS_LEVEL5_PUB_KEY_SIZE+SPHINCS_LEVEL5_KEY_SIZE)
+#endif
+
+#define SPHINCS_MAX_SIG_SIZE     SPHINCS_FAST_LEVEL5_SIG_SIZE
+#define SPHINCS_MAX_KEY_SIZE     SPHINCS_LEVEL5_PRV_KEY_SIZE
+#define SPHINCS_MAX_PUB_KEY_SIZE SPHINCS_LEVEL5_PUB_KEY_SIZE
+#define SPHINCS_MAX_PRV_KEY_SIZE SPHINCS_LEVEL5_PRV_KEY_SIZE
+
+#define FAST_VARIANT    1
+#define SMALL_VARIANT   2
+
+/* Structs */
+
+struct sphincs_key {
+    bool pubKeySet;
+    bool prvKeySet;
+    byte level; /* 1,3 or 5 */
+    byte optim; /* FAST_VARIANT or SMALL_VARIANT */
+    byte p[SPHINCS_MAX_PUB_KEY_SIZE];
+    byte k[SPHINCS_MAX_PRV_KEY_SIZE];
+};
+
+#ifndef WC_SPHINCSKEY_TYPE_DEFINED
+    typedef struct sphincs_key sphincs_key;
+    #define WC_SPHINCSKEY_TYPE_DEFINED
+#endif
+
+/* Functions */
+
+WOLFSSL_API
+int wc_sphincs_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
+                        sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
+                          word32 msgLen, int* res, sphincs_key* key);
+
+WOLFSSL_API
+int wc_sphincs_init(sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_set_level_and_optim(sphincs_key* key, byte level, byte optim);
+WOLFSSL_API
+int wc_sphincs_get_level_and_optim(sphincs_key* key, byte* level, byte *optim);
+WOLFSSL_API
+void wc_sphincs_free(sphincs_key* key);
+
+WOLFSSL_API
+int wc_sphincs_import_public(const byte* in, word32 inLen, sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_import_private_only(const byte* priv, word32 privSz,
+                                   sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_import_private_key(const byte* priv, word32 privSz,
+                                  const byte* pub, word32 pubSz,
+                                  sphincs_key* key);
+
+WOLFSSL_API
+int wc_sphincs_export_public(sphincs_key*, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_sphincs_export_private_only(sphincs_key* key, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_sphincs_export_private(sphincs_key* key, byte* out, word32* outLen);
+WOLFSSL_API
+int wc_sphincs_export_key(sphincs_key* key, byte* priv, word32 *privSz,
+                          byte* pub, word32 *pubSz);
+
+WOLFSSL_API
+int wc_sphincs_check_key(sphincs_key* key);
+
+WOLFSSL_API
+int wc_sphincs_size(sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_priv_size(sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_pub_size(sphincs_key* key);
+WOLFSSL_API
+int wc_sphincs_sig_size(sphincs_key* key);
+
+WOLFSSL_API int wc_Sphincs_PrivateKeyDecode(const byte* input,
+                                            word32* inOutIdx,
+                                            sphincs_key* key, word32 inSz);
+WOLFSSL_API int wc_Sphincs_PublicKeyDecode(const byte* input,
+                                           word32* inOutIdx,
+                                           sphincs_key* key, word32 inSz);
+WOLFSSL_API int wc_Sphincs_KeyToDer(sphincs_key* key, byte* output,
+                                    word32 inLen);
+WOLFSSL_API int wc_Sphincs_PrivateKeyToDer(sphincs_key* key, byte* output,
+                                           word32 inLen);
+WOLFSSL_API int wc_Sphincs_PublicKeyToDer(sphincs_key* key, byte* output,
+                                          word32 inLen, int withAlg);
+
+#ifdef __cplusplus
+    }    /* extern "C" */
+#endif
+
+#endif /* HAVE_PQC && HAVE_SPHINCS */
+#endif /* WOLF_CRYPT_SPHINCS_H */
diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h
index 8b24626be..5da08120b 100644
--- a/wolfssl/wolfcrypt/types.h
+++ b/wolfssl/wolfcrypt/types.h
@@ -945,6 +945,7 @@ typedef struct w64wrapper {
         DYNAMIC_TYPE_FALCON       = 95,
         DYNAMIC_TYPE_SESSION      = 96,
         DYNAMIC_TYPE_DILITHIUM    = 97,
+        DYNAMIC_TYPE_SPHINCS      = 98,
         DYNAMIC_TYPE_SNIFFER_SERVER     = 1000,
         DYNAMIC_TYPE_SNIFFER_SESSION    = 1001,
         DYNAMIC_TYPE_SNIFFER_PB         = 1002,