9#include <botan/internal/sp_wots.h> 
   11#include <botan/internal/sp_hash.h> 
   12#include <botan/internal/stl_util.h> 
   31   std::copy(wots_chain_key.begin(), wots_chain_key.end(), out.begin());
 
   34   for(
WotsHashIndex i = start; i < (start + steps) && i < params.w(); i++) {
 
   35      addr.set_hash_address(i);
 
   36      hashes.T(out, addr, out);
 
   46void base_2_b(std::span<WotsHashIndex> output, std::span<const uint8_t> input, 
const Sphincs_Parameters& params) {
 
   49   size_t input_offset = 0;
 
   50   uint8_t current_byte = 0;
 
   51   uint32_t remaining_bits_in_current_byte = 0;
 
   53   for(
auto& out : output) {
 
   54      if(remaining_bits_in_current_byte == 0) {
 
   55         current_byte = input[input_offset];
 
   57         remaining_bits_in_current_byte = 8;
 
   59      remaining_bits_in_current_byte -= params.log_w();
 
   60      out = 
WotsHashIndex((current_byte >> remaining_bits_in_current_byte) & (params.w() - 1));
 
   68void wots_checksum(std::span<WotsHashIndex> output,
 
   69                   std::span<const WotsHashIndex> msg_base_w,
 
   74   for(
auto wots_hash_index : msg_base_w) {
 
   75      csum += params.w() - 1 - wots_hash_index.get();
 
   79   csum = csum << ((8 - ((params.wots_len_2() * params.log_w()) % 8)) % 8);
 
   81   std::array<uint8_t, 4> csum_bytes{};
 
   84   const size_t csum_bytes_size = params.wots_checksum_bytes();
 
   86   base_2_b(output, std::span(csum_bytes).last(csum_bytes_size), params);
 
   94   auto msg_base_w = std::span(result).first(params.
wots_len_1());
 
   95   auto checksum_base_w = std::span(result).last(params.
wots_len_2());
 
   97   base_2_b(msg_base_w, msg.
get(), params);
 
   98   wots_checksum(checksum_base_w, msg_base_w, params);
 
 
  108   const std::vector<WotsHashIndex> lengths = 
chain_lengths(hashed_message, params);
 
  118      const uint8_t steps_to_take = 
static_cast<uint8_t
>(params.
w() - 1) - start_index.
get();
 
 
  136                         std::optional<TreeNodeIndex> sign_leaf_idx,
 
  137                         const std::vector<WotsHashIndex>& wots_steps,
 
  158      const auto wots_k = [&]() -> std::optional<WotsHashIndex> {
 
  159         if(sign_leaf_idx.has_value() && leaf_idx == sign_leaf_idx.value()) {
 
  160            return wots_steps[i.get()];
 
  173      hashes.
PRF(buffer_s, secret_seed, leaf_addr);
 
  180         if(wots_k.has_value() && k == wots_k.value()) {
 
  181            std::copy(buffer_s.begin(), buffer_s.end(), sig.
next<
WotsNode>(params.
n()).begin());
 
  185         if(k == params.
w() - 1) {
 
  192         hashes.
T(buffer_s, leaf_addr, buffer_s);
 
  197   hashes.
T(leaf_out, pk_addr, wots_pk_buffer);
 
 
#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)
 
Sphincs_Address_Type get_type() const
 
Sphincs_Address & set_chain_address(WotsChainIndex chain)
 
Sphincs_Address & set_hash_address(WotsHashIndex hash)
 
Sphincs_Address & set_keypair_address(TreeNodeIndex keypair)
 
Sphincs_Address & set_type(Sphincs_Address_Type type)
 
void T(std::span< uint8_t > out, const Sphincs_Address &address, const BufferTs &... in)
 
void PRF(StrongSpan< ForsLeafSecret > out, const SphincsSecretSeed &sk_seed, const Sphincs_Address &address)
 
uint32_t wots_bytes() const
 
uint32_t wots_len_2() const
 
uint32_t wots_len_1() const
 
uint32_t wots_len() const
 
Strong< std::vector< uint8_t >, struct SphincsTreeNode_ > SphincsTreeNode
Either an XMSS or FORS tree node or leaf.
 
@ WotsPublicKeyCompression
 
WotsPublicKey wots_public_key_from_signature(const SphincsTreeNode &hashed_message, StrongSpan< const WotsSignature > signature, Sphincs_Address &address, const Sphincs_Parameters ¶ms, Sphincs_Hash_Functions &hashes)
FIPS 205, Algorithm 8: wots_pkFromSig.
 
void wots_sign_and_pkgen(StrongSpan< WotsSignature > sig_out, StrongSpan< SphincsTreeNode > leaf_out, const SphincsSecretSeed &secret_seed, TreeNodeIndex leaf_idx, std::optional< TreeNodeIndex > sign_leaf_idx, const std::vector< WotsHashIndex > &wots_steps, Sphincs_Address &leaf_addr, Sphincs_Address &pk_addr, const Sphincs_Parameters ¶ms, Sphincs_Hash_Functions &hashes)
FIPS 205, Algorithm 6 and 7: wots_pkGen and wots_sign.
 
Strong< uint8_t, struct WotsHashIndex_, EnableArithmeticWithPlainNumber > WotsHashIndex
Index of a hash application inside a single WOTS chain (integers in "base_w")
 
Strong< secure_vector< uint8_t >, struct WotsNode_ > WotsNode
Start (or intermediate) node of a WOTS+ chain.
 
Strong< std::vector< uint8_t >, struct WotsPublicKey_ > WotsPublicKey
 
Strong< uint32_t, struct WotsChainIndex_ > WotsChainIndex
Index of a WOTS chain within a single usage of WOTS.
 
Strong< secure_vector< uint8_t >, struct SphincsSecretSeed_ > SphincsSecretSeed
 
Strong< std::vector< uint8_t >, struct WotsPublicKeyNode_ > WotsPublicKeyNode
End node of a WOTS+ chain (part of the WOTS+ public key)
 
Strong< uint32_t, struct TreeNodeIndex_, EnableArithmeticWithPlainNumber > TreeNodeIndex
Index of an individual node inside an XMSS or FORS tree.
 
std::vector< T, secure_allocator< T > > secure_vector
 
std::vector< WotsHashIndex > chain_lengths(const SphincsTreeNode &msg, const Sphincs_Parameters ¶ms)
 
constexpr auto store_be(ParamTs &&... params)