[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; +}