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);