11#include <botan/internal/sp_fors.h>
13#include <botan/assert.h>
14#include <botan/hash.h>
15#include <botan/sp_parameters.h>
17#include <botan/internal/sp_address.h>
18#include <botan/internal/sp_hash.h>
19#include <botan/internal/sp_treehash.h>
20#include <botan/internal/sp_types.h>
21#include <botan/internal/stl_util.h>
28std::vector<TreeNodeIndex> fors_message_to_indices(std::span<const uint8_t> message,
const Sphincs_Parameters& params) {
31 std::vector<TreeNodeIndex> indices(params.k());
36 auto update_idx = [&]() -> std::function<
void(
TreeNodeIndex&, uint32_t)> {
37#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
38 if(params.is_slh_dsa()) {
40 idx ^= (((message[offset >> 3] >> (~offset & 0x7)) & 0x1) << (params.a() - 1 - i));
44#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
45 if(!params.is_slh_dsa()) {
46 return [&](
TreeNodeIndex& idx, uint32_t i) { idx ^= (((message[offset >> 3] >> (offset & 0x7)) & 0x1) << i); };
49 throw Internal_Error(
"Missing FORS index update logic for SPHINCS+ or SLH-DSA");
52 for(
auto& idx : indices) {
53 for(uint32_t i = 0; i < params.a(); ++i, ++offset) {
71 const auto indices = fors_message_to_indices(hashed_message, params);
77 std::vector<uint8_t> roots_buffer(params.
k() * params.
n());
88 for(uint32_t i = 0; i < params.
k(); ++i) {
89 uint32_t idx_offset = i * (1 << params.
a());
94 .set_tree_index(indices[i] + idx_offset);
102 fors_tree_addr.set_tree_index(address_index);
105 hashes.
PRF(fors_leaf_secret, secret_seed, fors_tree_addr);
108 hashes.
T(out_root, fors_tree_addr, fors_leaf_secret);
134 const auto indices = fors_message_to_indices(hashed_message, params);
141 std::vector<uint8_t> roots_buffer(params.
k() * params.
n());
147 for(uint32_t i = 0; i < params.
k(); ++i) {
148 uint32_t idx_offset = i * (1 << params.
a());
151 fors_tree_addr.set_tree_height(
TreeLayerIndex(0)).set_tree_index(indices[i] + idx_offset);
#define BOTAN_ASSERT_NOMSG(expr)
std::span< const uint8_t > take(const size_t count)
Helper class to ease in-place marshalling of concatenated fixed-length values.
constexpr std::span< uint8_t > next(size_t bytes)
constexpr bool full() const
Sphincs_Address & set_type(Sphincs_Address_Type type)
static Sphincs_Address as_keypair_from(const Sphincs_Address &other)
void T(std::span< uint8_t > out, const Sphincs_Address &address, BufferTs &&... in)
void PRF(StrongSpan< ForsLeafSecret > out, const SphincsSecretSeed &sk_seed, const Sphincs_Address &address)
uint32_t fors_signature_bytes() const
decltype(auto) size() const noexcept(noexcept(this->m_span.size()))
SphincsTreeNode fors_sign_and_pkgen(StrongSpan< ForsSignature > sig_out, const SphincsHashedMessage &hashed_message, const SphincsSecretSeed &secret_seed, const Sphincs_Address &address, const Sphincs_Parameters ¶ms, Sphincs_Hash_Functions &hashes)
FIPS 205, Algorithm 16: fors_sign (with simultaneous FORS pk generation)
std::function< void(StrongSpan< SphincsTreeNode >, TreeNodeIndex)> GenerateLeafFunction
Strong< uint32_t, struct TreeNodeIndex_, EnableArithmeticWithPlainNumber > TreeNodeIndex
Index of an individual node inside an XMSS or FORS tree.
SphincsTreeNode fors_public_key_from_signature(const SphincsHashedMessage &hashed_message, StrongSpan< const ForsSignature > signature, const Sphincs_Address &address, const Sphincs_Parameters ¶ms, Sphincs_Hash_Functions &hashes)
FIPS 205, Algorithm 17: fors_pkFromSig.
Strong< uint32_t, struct TreeLayerIndex_, EnableArithmeticWithPlainNumber > TreeLayerIndex
Index of the layer within a FORS/XMSS tree.
void treehash(StrongSpan< SphincsTreeNode > out_root, StrongSpan< SphincsAuthenticationPath > out_auth_path, const Sphincs_Parameters ¶ms, Sphincs_Hash_Functions &hashes, std::optional< TreeNodeIndex > leaf_idx, uint32_t idx_offset, uint32_t total_tree_height, const GenerateLeafFunction &gen_leaf, Sphincs_Address &tree_address)
void compute_root(StrongSpan< SphincsTreeNode > out, const Sphincs_Parameters ¶ms, Sphincs_Hash_Functions &hashes, const SphincsTreeNode &leaf, TreeNodeIndex leaf_idx, uint32_t idx_offset, StrongSpan< const SphincsAuthenticationPath > authentication_path, uint32_t total_tree_height, Sphincs_Address &tree_address)