8 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/verify.h" 
   14 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/address.h" 
   15 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/context.h" 
   16 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/fors.h" 
   17 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/hash.h" 
   18 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/params.h" 
   19 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/thash.h" 
   20 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/utils.h" 
   21 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/wots.h" 
   23 static_assert(kSpxVerifySigWords * 
sizeof(uint32_t) == kSpxVerifySigBytes,
 
   24               "kSpxVerifySigWords and kSpxVerifySigBytes do not match.");
 
   25 static_assert(kSpxVerifyPkWords * 
sizeof(uint32_t) == kSpxVerifyPkBytes,
 
   26               "kSpxVerifyPkWords and kSpxVerifyPkBytes do not match.");
 
   27 static_assert(kSpxD <= UINT8_MAX, 
"kSpxD must fit into a uint8_t.");
 
   28 rom_error_t spx_verify(
const uint32_t *sig, 
const uint8_t *msg_prefix_1,
 
   29                        size_t msg_prefix_1_len, 
const uint8_t *msg_prefix_2,
 
   30                        size_t msg_prefix_2_len, 
const uint8_t *msg_prefix_3,
 
   31                        size_t msg_prefix_3_len, 
const uint8_t *msg,
 
   32                        size_t msg_len, 
const uint32_t *pk, uint32_t *root) {
 
   38   HARDENED_RETURN_IF_ERROR(spx_hash_initialize(&ctx));
 
   43   spx_addr_type_set(&wots_addr, kSpxAddrTypeWots);
 
   44   spx_addr_type_set(&tree_addr, kSpxAddrTypeHashTree);
 
   45   spx_addr_type_set(&wots_pk_addr, kSpxAddrTypeWotsPk);
 
   49   uint8_t mhash[kSpxForsMsgBytes];
 
   52   HARDENED_RETURN_IF_ERROR(spx_hash_message(
 
   53       sig, pk, msg_prefix_1, msg_prefix_1_len, msg_prefix_2, msg_prefix_2_len,
 
   54       msg_prefix_3, msg_prefix_3_len, msg, msg_len, mhash, &tree, &idx_leaf));
 
   58   spx_addr_tree_set(&wots_addr, tree);
 
   59   spx_addr_keypair_set(&wots_addr, idx_leaf);
 
   61   fors_pk_from_sig(sig, mhash, &ctx, &wots_addr, root);
 
   65   for (uint8_t i = 0; i < kSpxD; i++) {
 
   66     spx_addr_layer_set(&tree_addr, i);
 
   67     spx_addr_tree_set(&tree_addr, tree);
 
   69     spx_addr_subtree_copy(&wots_addr, &tree_addr);
 
   70     spx_addr_keypair_set(&wots_addr, idx_leaf);
 
   72     spx_addr_keypair_copy(&wots_pk_addr, &wots_addr);
 
   77     uint32_t wots_pk[kSpxWotsWords];
 
   78     wots_pk_from_sig(sig, root, &ctx, &wots_addr, wots_pk);
 
   82     uint32_t leaf[kSpxNWords];
 
   83     thash(wots_pk, kSpxWotsLen, &ctx, &wots_pk_addr, leaf);
 
   86     spx_utils_compute_root(leaf, idx_leaf, 0, sig, kSpxTreeHeight, &ctx,
 
   88     sig += kSpxTreeHeight * kSpxNWords;
 
   91     idx_leaf = (tree & ((1 << kSpxTreeHeight) - 1));
 
   92     tree = tree >> kSpxTreeHeight;
 
   98 inline void spx_public_key_root(
const uint32_t *pk, uint32_t *root) {
 
   99   memcpy(root, pk + kSpxNWords, kSpxN);