Botan 3.11.0
Crypto and TLS for C&
xmss_signature_operation.cpp
Go to the documentation of this file.
1/*
2 * XMSS Signature Operation
3 * Signature generation operation for Extended Hash-Based Signatures (XMSS) as
4 * defined in:
5 *
6 * [1] XMSS: Extended Hash-Based Signatures,
7 * Request for Comments: 8391
8 * Release: May 2018.
9 * https://datatracker.ietf.org/doc/rfc8391/
10 *
11 * (C) 2016,2017,2018 Matthias Gierlings
12 * 2026 Jack Lloyd
13 *
14 * Botan is released under the Simplified BSD License (see license.txt)
15 **/
16
17#include <botan/internal/xmss_signature_operation.h>
18
19#include <botan/internal/xmss_tools.h>
20
21namespace Botan {
22
24 m_priv_key(private_key),
25 m_hash(private_key.xmss_parameters()),
26 m_randomness(0),
27 m_leaf_idx(0),
28 m_is_initialized(false) {}
29
31 const auto& params = m_priv_key.xmss_parameters();
32 return sizeof(uint64_t) + // size of leaf index
33 params.element_size() + params.len() * params.element_size() + params.tree_height() * params.element_size();
34}
35
36void XMSS_Signature_Operation::update(std::span<const uint8_t> input) {
37 initialize();
38 m_hash.h_msg_update(input);
39}
40
42 initialize();
43
44 const auto msg_hash = m_hash.h_msg_final();
45
46 const auto& params = m_priv_key.xmss_parameters();
47 wots_keysig_t auth_path(params.tree_height());
48
49 XMSS_Address adrs;
51
52 for(size_t j = 0; j < params.tree_height(); j++) {
53 const size_t k = (m_leaf_idx / (static_cast<size_t>(1) << j)) ^ 0x01;
54 auth_path[j] = m_priv_key.tree_hash(k * (static_cast<size_t>(1) << j), j, adrs, m_hash);
55 }
56
58 adrs.set_ots_address(m_leaf_idx);
59
61 tree_sig.authentication_path = auth_path;
62 tree_sig.ots_signature =
63 m_priv_key.wots_private_key_for(adrs, m_hash).sign(msg_hash, m_priv_key.public_seed(), adrs, m_hash);
64
65 const XMSS_Signature sig(m_leaf_idx, m_randomness, tree_sig);
66 m_is_initialized = false;
67 return sig.bytes();
68}
69
70void XMSS_Signature_Operation::initialize() {
71 // return if we already initialized and reserved a leaf index for signing.
72 if(m_is_initialized) {
73 return;
74 }
75
76 secure_vector<uint8_t> index_bytes;
77 // reserve leaf index so it can not be reused by another signature
78 // operation using the same private key.
79 m_leaf_idx = static_cast<uint32_t>(m_priv_key.reserve_unused_leaf_index());
80
81 // write prefix for message hashing into buffer.
82 xmss_concat(index_bytes, m_leaf_idx, 32);
83 m_hash.prf(m_randomness, m_priv_key.prf_value(), index_bytes);
84 index_bytes.clear();
85 xmss_concat(index_bytes, m_leaf_idx, m_priv_key.xmss_parameters().element_size());
86 m_hash.h_msg_init(m_randomness, m_priv_key.root(), index_bytes);
87 m_is_initialized = true;
88}
89
93
94} // namespace Botan
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:86
void set_ots_address(uint32_t value)
void set_type(Type type)
void prf(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition xmss_hash.h:57
void h_msg_init(std::span< const uint8_t > randomness, std::span< const uint8_t > root, std::span< const uint8_t > index_bytes)
Definition xmss_hash.cpp:35
size_t element_size() const
const secure_vector< uint8_t > & root() const
Definition xmss.h:116
const XMSS_Parameters & xmss_parameters() const
Definition xmss.h:118
XMSS_Signature_Operation(const XMSS_PrivateKey &private_key)
AlgorithmIdentifier algorithm_identifier() const override
std::vector< uint8_t > sign(RandomNumberGenerator &rng) override
void update(std::span< const uint8_t > input) override
std::vector< uint8_t > bytes() const
std::vector< secure_vector< uint8_t > > wots_keysig_t
void xmss_concat(secure_vector< uint8_t > &target, const T &src)
Definition xmss_tools.h:28
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68