9#include <botan/internal/sp_wots.h>
11#include <botan/internal/sp_hash.h>
12#include <botan/internal/stl_util.h>
21void gen_chain(StrongSpan<WotsPublicKeyNode> out,
22 StrongSpan<const WotsNode> wots_chain_key,
25 Sphincs_Address& addr,
26 Sphincs_Hash_Functions& hashes,
27 const Sphincs_Parameters& params) {
29 std::copy(wots_chain_key.begin(), wots_chain_key.end(), out.begin());
32 for(
WotsHashIndex i = start; i < (start + steps) && i < params.w(); i++) {
34 hashes.T(out, addr, out);
43void base_w(std::span<WotsHashIndex> output, std::span<const uint8_t> input,
const Sphincs_Parameters& params) {
46 size_t input_offset = 0;
47 uint8_t current_byte = 0;
48 uint32_t remaining_bits_in_current_byte = 0;
50 for(
auto& out : output) {
51 if(remaining_bits_in_current_byte == 0) {
52 current_byte = input[input_offset];
54 remaining_bits_in_current_byte = 8;
56 remaining_bits_in_current_byte -= params.log_w();
57 out =
WotsHashIndex((current_byte >> remaining_bits_in_current_byte) & (params.w() - 1));
62void wots_checksum(std::span<WotsHashIndex> output,
63 std::span<const WotsHashIndex> msg_base_w,
64 const Sphincs_Parameters& params) {
68 for(
auto wots_hash_index : msg_base_w) {
69 csum += params.w() - 1 - wots_hash_index.get();
73 csum = csum << ((8 - ((params.wots_len_2() * params.log_w()) % 8)) % 8);
75 std::array<uint8_t, 4> csum_bytes;
78 const size_t csum_bytes_size = params.wots_checksum_bytes();
80 base_w(output, std::span(csum_bytes).last(csum_bytes_size), params);
88 auto msg_base_w = std::span(result).first(params.
wots_len_1());
89 auto checksum_base_w = std::span(result).last(params.
wots_len_2());
91 base_w(msg_base_w, msg.
get(), params);
92 wots_checksum(checksum_base_w, msg_base_w, params);
102 const std::vector<WotsHashIndex> lengths =
chain_lengths(hashed_message, params);
112 const uint8_t steps_to_take =
static_cast<uint8_t
>(params.
w() - 1) - start_index.
get();
130 std::optional<TreeNodeIndex> sign_leaf_idx,
131 const std::vector<WotsHashIndex>& wots_steps,
152 const auto wots_k = [&]() -> std::optional<WotsHashIndex> {
153 if(sign_leaf_idx.has_value() && leaf_idx == sign_leaf_idx.value()) {
154 return wots_steps[i.get()];
167 hashes.
PRF(buffer_s, secret_seed, leaf_addr);
174 if(wots_k.has_value() && k == wots_k.value()) {
179 if(k == params.
w() - 1) {
186 hashes.
T(buffer_s, leaf_addr, buffer_s);
191 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 & set_chain(WotsChainIndex chain)
Sphincs_Address_Type get_type() const
Sphincs_Address & set_keypair(TreeNodeIndex keypair)
Sphincs_Address & set_hash(WotsHashIndex hash)
Sphincs_Address & set_type(Sphincs_Address_Type type)
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 wots_bytes() const
uint32_t wots_len_2() const
uint32_t wots_len_1() const
uint32_t wots_len() const
decltype(auto) begin() noexcept(noexcept(this->get().begin()))
@ 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)
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)
Strong< uint8_t, struct WotsHashIndex_, EnableArithmeticWithPlainNumber > WotsHashIndex
Index of a hash application inside a single WOTS chain (integers in "base_w")
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)