[crypto] Add a basic functional test for FORS.

Signed-off-by: Jade Philipoom <jadep@google.com>
diff --git a/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/BUILD b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/BUILD
index 08465de..94ccae5 100644
--- a/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/BUILD
+++ b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/BUILD
@@ -11,6 +11,24 @@
 )
 
 opentitan_functest(
+    name = "fors_test",
+    srcs = ["fors_test.c"],
+    verilator = verilator_params(
+        timeout = "long",
+    ),
+    deps = [
+        "//sw/device/lib/base:memory",
+        "//sw/device/lib/runtime:ibex",
+        "//sw/device/lib/runtime:log",
+        "//sw/device/lib/testing/test_framework:ottf_main",
+        "//sw/device/silicon_creator/lib:test_main",
+        "//sw/device/silicon_creator/lib/sigverify/sphincsplus:context",
+        "//sw/device/silicon_creator/lib/sigverify/sphincsplus:fors",
+        "//sw/device/silicon_creator/lib/sigverify/sphincsplus:hash",
+    ],
+)
+
+opentitan_functest(
     name = "wots_test",
     srcs = ["wots_test.c"],
     verilator = verilator_params(
diff --git a/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/fors_test.c b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/fors_test.c
new file mode 100644
index 0000000..86ed73c
--- /dev/null
+++ b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/fors_test.c
@@ -0,0 +1,71 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/silicon_creator/lib/sigverify/sphincsplus/fors.h"
+
+#include <stdint.h>
+
+#include "sw/device/lib/runtime/ibex.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+#include "sw/device/silicon_creator/lib/sigverify/sphincsplus/hash.h"
+#include "sw/device/silicon_creator/lib/test_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+
+// Test signature and message. Populate before running test.
+static uint8_t kTestSig[kSpxForsBytes] = {0};
+static uint8_t kTestMsg[kSpxForsMsgBytes] = {0};
+
+// Test context.
+static spx_ctx_t kTestCtx = {
+    .pub_seed = {0xefbeadde},
+};
+
+// Test address.
+static spx_addr_t kTestAddr = {.addr = {0}};
+
+// This test data was generated by simply running the FORS pk-from-sig function
+// from a version where the overall `verify` operation was consistently passing
+// tests. Standalone test vectors for FORS don't seem to exist at time of
+// writing.
+//
+// Note: this expected public key is based on the sphincs-shake-128s
+// parameter set and will not work for other parameter sets.
+static uint32_t kExpectedPk[kSpxNWords] = {0xd2c5c792, 0x80d096bd, 0xdb6d692e,
+                                           0xf75f2fe8};
+
+static rom_error_t pk_from_sig_test(void) {
+  // Initialize the KMAC block.
+  RETURN_IF_ERROR(spx_hash_initialize(&kTestCtx));
+
+  // Extract the public key from the signature.
+  uint32_t actual_pk[kSpxNWords];
+  RETURN_IF_ERROR(
+      fors_pk_from_sig(kTestSig, kTestMsg, &kTestCtx, &kTestAddr, actual_pk));
+
+  // Check results.
+  CHECK_ARRAYS_EQ(actual_pk, kExpectedPk, kSpxNWords);
+  return kErrorOk;
+}
+
+bool test_main() {
+  rom_error_t result = kErrorOk;
+  LOG_INFO("Starting FORS test...");
+
+  // Populate signature with {0, 1, 2, 3, ... }.
+  for (size_t i = 0; i < kSpxForsBytes; i++) {
+    kTestSig[i] = i & 255;
+  }
+
+  // Populate message with { ..., 3, 2, 1, 0}.
+  for (size_t i = 0; i < kSpxForsMsgBytes; i++) {
+    kTestMsg[i] = (kSpxForsMsgBytes - i) & 255;
+  }
+
+  EXECUTE_TEST(result, pk_from_sig_test);
+
+  return result == kErrorOk;
+}
diff --git a/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/wots_test.c b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/wots_test.c
index 1e57ed7..74a61df 100644
--- a/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/wots_test.c
+++ b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/wots_test.c
@@ -22,7 +22,7 @@
 
 // Test signature and message. Populate before running test.
 static uint8_t kTestSig[kSpxWotsBytes] = {0};
-static uint8_t kTestMsg[kSpxWotsBytes] = {0};
+static uint8_t kTestMsg[kSpxWotsMsgBytes] = {0};
 
 // Test context.
 static spx_ctx_t kTestCtx = {