[crypto] Add a basic functional test for WOTS.
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
new file mode 100644
index 0000000..08465de
--- /dev/null
+++ b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/BUILD
@@ -0,0 +1,29 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+package(default_visibility = ["//visibility:public"])
+
+load(
+ "//rules:opentitan_test.bzl",
+ "opentitan_functest",
+ "verilator_params",
+)
+
+opentitan_functest(
+ name = "wots_test",
+ srcs = ["wots_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:hash",
+ "//sw/device/silicon_creator/lib/sigverify/sphincsplus:wots",
+ ],
+)
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
new file mode 100644
index 0000000..1e57ed7
--- /dev/null
+++ b/sw/device/silicon_creator/lib/sigverify/sphincsplus/test/wots_test.c
@@ -0,0 +1,100 @@
+// 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/wots.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/sigverify/sphincsplus/params.h"
+#include "sw/device/silicon_creator/lib/test_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+
+enum {
+ kSpxWotsMsgBytes = ((kSpxWotsLen1 * kSpxWotsLogW + 7) / 8),
+};
+
+// Test signature and message. Populate before running test.
+static uint8_t kTestSig[kSpxWotsBytes] = {0};
+static uint8_t kTestMsg[kSpxWotsBytes] = {0};
+
+// Test context.
+static spx_ctx_t kTestCtx = {
+ .pub_seed = {0xefbeadde},
+};
+
+// Test address.
+static spx_addr_t kTestAddr = {.addr = {0xdeadbeef}};
+
+// This test data was generated by simply running the WOTS pk-from-sig function
+// from a version where the overall `verify` operation was consistently passing
+// tests. Standalone test vectors for WOTS don't seem to exist at time of
+// writing.
+//
+// Note: this public key is based on the sphincs-shake-128s parameter set and
+// will not work for other parameter sets.
+static const uint32_t kExpectedPk[kSpxWotsPkWords] = {
+ 0x2664c607, 0x0876f157, 0x07fca058, 0x1edd1978, 0xd34ea8b2, 0xc635e08a,
+ 0x2ad601bc, 0x430f5e4e, 0xc1cdf74a, 0x07e2186b, 0xd37b8f28, 0x27d2e280,
+ 0x33323130, 0x37363534, 0x3b3a3938, 0x3f3e3d3c, 0x5dbc5771, 0xdf3fb927,
+ 0x785e5aec, 0xcc6e1dae, 0x86b2f0d0, 0xa2b45f3a, 0x9778f47b, 0x6f5fe9a9,
+ 0xce0cbe16, 0x8d29f3cc, 0x218035e4, 0x82fe66ca, 0xd44fc3e2, 0xd6e2eb92,
+ 0xc84c5020, 0xe67a8ad9, 0xdee8a9e1, 0x35520ee2, 0xe43c747a, 0x1a9520db,
+ 0x5a582887, 0x27e4abcc, 0x6a9e2dcd, 0x4150bbb2, 0xe9ca7143, 0xde01a332,
+ 0x92824132, 0x75b6dbbb, 0xa820737c, 0x403fabff, 0xebdc9b14, 0xb0e8d941,
+ 0x8cdc02ef, 0xcb00b6ad, 0x06a98cf7, 0xe5d16eea, 0x7eccf7a8, 0x1f036a59,
+ 0x663cb396, 0xa4768d91, 0x6d1ca9b5, 0xe5ea1254, 0x6a585c9f, 0x3fff5c4c,
+ 0xb2ac73f7, 0x498b2717, 0xa6352ba5, 0x110d3b1f, 0x25acdf7e, 0xc49b07e2,
+ 0x4580c93c, 0x6c0d5125, 0xb51ea2de, 0xe90ea294, 0xf2b1f7e7, 0xb98d2ca7,
+ 0x67507c3f, 0x4278d9df, 0x459e0d22, 0x6d808a83, 0x50b29e70, 0xbeb49d1a,
+ 0xe5d50a2f, 0xe18caf8f, 0xb9670acb, 0xc02fb41c, 0x02b64bb2, 0x3e1ed1b6,
+ 0xf82d3afc, 0x1936bc72, 0xad75f064, 0xfc89d191, 0xea091797, 0xbd7a778a,
+ 0x1aafd227, 0xbe35349e, 0x8e5aa563, 0xaf19f168, 0x9fc76c94, 0xfb0ab2ed,
+ 0x72c5dacd, 0x023d3a50, 0x49a90a2e, 0x38d6eaae, 0x4e37cfcf, 0xf96a6d87,
+ 0xb50a84c1, 0x2a409f21, 0xf94235b1, 0x136ef5ea, 0x0fd2c77e, 0x95b2f59a,
+ 0x7acddc7f, 0x6154fdba, 0x43b556dc, 0x44ad8f0c, 0xeab603d5, 0x5888600b,
+ 0x6c5c4b67, 0x4cf25965, 0xbafafd38, 0x974ff50b, 0x34239d92, 0xa4884b71,
+ 0x4f7469f5, 0xd5f10fc0, 0xacce2fac, 0x2b774cb6, 0x5d88c301, 0x11f0575d,
+ 0x984a4fdd, 0x5f44b01d, 0x77ed6afa, 0x272edd0c, 0xa5a9ded1, 0x34a55aba,
+ 0x460bec28, 0x3724f477, 0x46f9003f, 0x6357d6ec, 0x7a39121d, 0x511b498f,
+ 0x2bca40d1, 0x24b829a1};
+
+static rom_error_t pk_from_sig_test() {
+ // Initialize the KMAC block.
+ RETURN_IF_ERROR(spx_hash_initialize(&kTestCtx));
+
+ // Extract the public key from the signature.
+ uint32_t actual_pk[kSpxWotsPkWords];
+ RETURN_IF_ERROR(
+ wots_pk_from_sig(kTestSig, kTestMsg, &kTestCtx, &kTestAddr, actual_pk));
+
+ // Check results.
+ CHECK_ARRAYS_EQ(actual_pk, kExpectedPk, kSpxWotsPkWords);
+
+ return kErrorOk;
+}
+
+bool test_main() {
+ rom_error_t result = kErrorOk;
+ LOG_INFO("Starting WOTS test...");
+
+ // Populate signature with {0, 1, 2, 3, ... }.
+ for (size_t i = 0; i < kSpxWotsBytes; i++) {
+ kTestSig[i] = i & 255;
+ }
+
+ // Populate message with { ..., 3, 2, 1, 0}.
+ for (size_t i = 0; i < kSpxWotsMsgBytes; i++) {
+ kTestMsg[i] = (kSpxWotsMsgBytes - i) & 255;
+ }
+
+ EXECUTE_TEST(result, pk_from_sig_test);
+
+ return result == kErrorOk;
+}