8 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/fors.h"
10 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/address.h"
11 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/hash.h"
12 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/thash.h"
13 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/utils.h"
23 static void fors_sk_to_leaf(
const uint32_t *sk,
const spx_ctx_t *ctx,
25 return thash(sk, 1, ctx, fors_leaf_addr, leaf);
37 static void message_to_indices(
const uint8_t *m, uint32_t *indices) {
39 for (
size_t i = 0; i < kSpxForsTrees; i++) {
41 for (
size_t j = 0; j < kSpxForsHeight; j++) {
42 indices[i] ^= ((m[offset >> 3] >> (~offset & 0x7u)) & 0x1u)
43 << (kSpxForsHeight - 1 - j);
49 void fors_pk_from_sig(
const uint32_t *sig,
const uint8_t *m,
54 spx_addr_keypair_copy(&fors_tree_addr, fors_addr);
55 spx_addr_type_set(&fors_tree_addr, kSpxAddrTypeForsTree);
59 spx_addr_keypair_copy(&fors_pk_addr, fors_addr);
60 spx_addr_type_set(&fors_pk_addr, kSpxAddrTypeForsPk);
62 uint32_t indices[kSpxForsTrees];
63 message_to_indices(m, indices);
65 uint32_t roots[kSpxForsTrees * kSpxNWords];
66 for (
size_t i = 0; i < kSpxForsTrees; i++) {
67 uint32_t idx_offset = i * (1 << kSpxForsHeight);
69 spx_addr_tree_height_set(&fors_tree_addr, 0);
70 spx_addr_tree_index_set(&fors_tree_addr, indices[i] + idx_offset);
73 uint32_t leaf[kSpxNWords];
74 fors_sk_to_leaf(sig, ctx, &fors_tree_addr, leaf);
78 uint32_t *root = &roots[i * kSpxNWords];
79 spx_utils_compute_root(leaf, indices[i], idx_offset, sig, kSpxForsHeight,
80 ctx, &fors_tree_addr, root);
81 sig += kSpxNWords * kSpxForsHeight;
85 thash(roots, kSpxForsTrees, ctx, &fors_pk_addr, pk);