[mask_rom, sig_verify] Add tests for mont_mul

Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/tests/meson.build b/sw/device/tests/meson.build
index 0c67b4f..aa27812 100644
--- a/sw/device/tests/meson.build
+++ b/sw/device/tests/meson.build
@@ -29,6 +29,7 @@
 subdir('rom_ext')
 subdir('runtime')
 subdir('sca')
+subdir('silicon_creator')
 subdir('sim_dv')
 subdir('otbn')
 
diff --git a/sw/device/tests/silicon_creator/mask_rom/meson.build b/sw/device/tests/silicon_creator/mask_rom/meson.build
new file mode 100644
index 0000000..6e32aed
--- /dev/null
+++ b/sw/device/tests/silicon_creator/mask_rom/meson.build
@@ -0,0 +1,15 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+test('rsa_verify_unittest', executable(
+  'rsa_verify_unittest',
+  sources: [
+    meson.source_root() / 'sw/device/silicon_creator/mask_rom/rsa_verify.c',
+    'rsa_verify_unittest.cc',
+  ],
+  dependencies: [
+    sw_vendor_gtest,
+  ],
+  native: true,
+))
diff --git a/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc b/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc
new file mode 100644
index 0000000..45392e8
--- /dev/null
+++ b/sw/device/tests/silicon_creator/mask_rom/rsa_verify_unittest.cc
@@ -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/mask_rom/rsa_verify.h"
+
+#include "gtest/gtest.h"
+
+namespace rsa_verify_unittest {
+namespace {
+
+// Convenience alias for mont_mul parameters.
+using RsaBuffer = std::array<uint32_t, kRsaNumWords>;
+
+TEST(MontMul, SmallNumbers) {
+  // Values are from ex. 14.35 in Handbook of Applied Cryptography except for m'
+  // and expected result are computed for base 2^32 and R = 2^3072 (96 base 2^32
+  // digits):
+  // - m' = -m^-1 mod b = 3837733825
+  // - R^-1 mod m = 72136
+  // - x * y * R^-1 mod m = 55123
+  constexpr RsaBuffer x{5792};
+  constexpr RsaBuffer y{1229};
+  constexpr RsaBuffer m{72639};
+  constexpr uint32_t m_prime = 3837733825;
+  constexpr RsaBuffer exp_result{55123};
+  // Uninitialized on purpose.
+  RsaBuffer act_res;
+
+  mont_mul(x.data(), y.data(), m.data(), m_prime, act_res.data());
+
+  EXPECT_EQ(exp_result, act_res);
+}
+
+TEST(MontMul, LargeNumbers) {
+  constexpr RsaBuffer m{
+      0x6a6a75e1, 0xa018ddc5, 0x687bb168, 0x8e8205a5, 0x7dbfffa7, 0xc8722ac5,
+      0xf84d21cf, 0xe1312531, 0x0ce3f8a3, 0xa825f988, 0x57f51964, 0xb27e206a,
+      0x8e1dd008, 0x1c4fb8d7, 0x824fb142, 0x1c8be7b3, 0x7b9d6366, 0xc56ad0f2,
+      0xef762d5b, 0x4b1431e3, 0x8ae28eb9, 0xd41db7aa, 0x43cccdf7, 0x91b74a84,
+      0x80183850, 0x30e74d0d, 0xb62ed015, 0x235574d2, 0x8c28f251, 0x4f40def2,
+      0x24e2efdb, 0x9ebd1ff2, 0xfa7b49ee, 0x2819a938, 0x6e66b8c8, 0x24e41546,
+      0x4d783a7c, 0xd2947d3d, 0x1ab269e9, 0xfad39f16, 0xaab78f7b, 0x49d8b510,
+      0x35bf0dfb, 0xeb274754, 0x069eccc9, 0xc13c437e, 0xe3bc0f60, 0xc9e0e12f,
+      0xc253ac43, 0x89c240e0, 0xc4aba4e5, 0xedf34bc0, 0x5402c462, 0x4021b0bd,
+      0x996b6241, 0xc3d9945f, 0xa137ac60, 0xf0250bf5, 0xc8c7100f, 0xb70d6b88,
+      0x78916a8c, 0x33370e5d, 0x3970dcb9, 0xaf4c58b4, 0x5f78cb0d, 0xb02d90b7,
+      0xeb6c3d05, 0x04afc71a, 0x45185f0f, 0x987caa5b, 0x33976249, 0x565afdbc,
+      0x80a85056, 0x59e07655, 0x9a29e77d, 0x7a8dfb7f, 0x782e0204, 0x4d6713ff,
+      0x131000ea, 0xe18e1206, 0x21f57f30, 0xf24f038b, 0x59cf874d, 0x24c50525,
+      0xb52f170d, 0x46c9adde, 0x90e82c73, 0x1344ceaf, 0x663209f2, 0x24bd4fbf,
+      0x5e4ed04d, 0x0fce770a, 0x81f78793, 0xa792e13e, 0xa6c7bf58, 0xe1df9be8,
+  };
+  constexpr RsaBuffer sig{
+      0xceb7e983, 0xe693b200, 0xf9153989, 0xcf899599, 0x1ec09fae, 0xf2f88007,
+      0x2a24eed5, 0x9c5b7c4e, 0x21a153b2, 0xaf7583ae, 0x04fdd694, 0x7550094b,
+      0xb2a69ac4, 0xe49d8022, 0x7ed6f162, 0x14bb3a1b, 0xbb29d8dd, 0x5c5815c2,
+      0x7a80d848, 0xb122f449, 0x59dca808, 0xbc1443e2, 0xe304ff93, 0xcc97ee4b,
+      0x42ef6b57, 0x1436839f, 0xae860b45, 0x6a843a17, 0x2381fb91, 0x09fd0635,
+      0xa431aac3, 0xd7220269, 0xdf3e2697, 0x35e2915e, 0xedba6956, 0x1d387448,
+      0x930006df, 0x961e5f00, 0xf2a7e960, 0x884e4add, 0x7dfe76b1, 0x4079aa79,
+      0x1f3a378d, 0x96c20697, 0x268aea57, 0x2c8569a4, 0x0474f512, 0x2388555c,
+      0x58679953, 0xe73da3a0, 0x43431b9a, 0x699f04d3, 0xfc0be066, 0xcce606f2,
+      0xd94cdfa0, 0x6c1ddca3, 0xe96c11f6, 0xfc635db4, 0x3bdb4f69, 0xa621c3e7,
+      0x9f292111, 0xb86e1e6b, 0xb74f923b, 0x592967a0, 0xc412097f, 0x8c1c8ca7,
+      0x494fcdb6, 0x87c5fe0f, 0x50c01aee, 0x8a26368e, 0xeaf12232, 0x7dade4d8,
+      0x39eb2ac6, 0x744f8aaa, 0xf34908ca, 0x1e0c656c, 0xe96d4e29, 0x8575d194,
+      0xe439bd31, 0xa74a77e3, 0x0f465b88, 0xf4e21152, 0x80400ad8, 0xe58501ec,
+      0xa29d7536, 0x55c19326, 0x9ebbc63e, 0x20c75aee, 0xef6783d7, 0x59ffdba5,
+      0x879b937b, 0x43a5c74c, 0x82b8f825, 0xfdf04b3a, 0x8fc62fbe, 0x114e6da5,
+  };
+  constexpr uint32_t m_prime = 4036719071;
+  constexpr RsaBuffer exp_result{
+      0x7603d6bd, 0xe7714c93, 0x97cf4c0a, 0xa2f79f2b, 0xd6d9a47a, 0x666d8e1d,
+      0x298e418a, 0xdbb713ec, 0x84d319fd, 0x1e89e6c3, 0xa4671f40, 0xc324a13b,
+      0x528c47d0, 0xa4dd82ef, 0x07d00906, 0xa42d7bc9, 0xdaa7dabb, 0x7833ef95,
+      0x8bd072e1, 0x79cc5b32, 0x0acce463, 0x72341597, 0x48771929, 0x7ed99ffe,
+      0x16c6323b, 0x79dfb968, 0xf0a209fe, 0x7f92c8aa, 0x0f1588aa, 0xc83fdf6f,
+      0x5711982a, 0x2dae9583, 0x7cb22468, 0x646a7389, 0x5dde7838, 0x3d7bfa5e,
+      0xf044da0c, 0xe18031a3, 0x41f219eb, 0x137f03e7, 0xeee7e63b, 0x0ca6e484,
+      0x7a7834fd, 0x9dc43ffe, 0x2e577301, 0xf35042b3, 0x6617b57c, 0xda6b7dc4,
+      0xf8a6dd5b, 0x67059290, 0x86866edc, 0x094355af, 0xc7989f1a, 0x10a9d520,
+      0xda9ee036, 0x7e54f825, 0xbcd4f122, 0xe3e10de1, 0xed1d7412, 0xd84936df,
+      0x2afb47dd, 0xee084c01, 0xf3dc8101, 0x56e4539c, 0xf16a855a, 0x3e09bf8f,
+      0xa01e4b9d, 0x09791f8b, 0x94e0ffc6, 0x698b0428, 0x066418c3, 0x418bf9fa,
+      0x9e07ba2a, 0xf5487bfd, 0x7e4ddea5, 0x31086807, 0x4c4cc5d9, 0xb4e58126,
+      0x9bb65989, 0xf88824e9, 0xd97fb609, 0xa4cafb2e, 0x932e86d1, 0x59f0d7d2,
+      0x71df95b3, 0x083ec525, 0x0759cea9, 0xe487335d, 0xbeb42a5c, 0x7dc33154,
+      0x59e45235, 0x11ca6d14, 0x43334239, 0xfe7cd561, 0xb161f750, 0xafcef8de,
+  };
+  // Uninitialized on purpose.
+  RsaBuffer act_res;
+
+  mont_mul(sig.data(), sig.data(), m.data(), m_prime, act_res.data());
+
+  EXPECT_EQ(exp_result, act_res);
+}
+
+}  // namespace
+}  // namespace rsa_verify_unittest
diff --git a/sw/device/tests/silicon_creator/meson.build b/sw/device/tests/silicon_creator/meson.build
new file mode 100644
index 0000000..caaaf8e
--- /dev/null
+++ b/sw/device/tests/silicon_creator/meson.build
@@ -0,0 +1,5 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+subdir('mask_rom')