Botan 3.6.1
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 *
13 * Botan is released under the Simplified BSD License (see license.txt)
14 **/
15
16#include <botan/internal/xmss_signature_operation.h>
17
18#include <botan/internal/xmss_tools.h>
19
20namespace Botan {
21
23 m_priv_key(private_key),
24 m_hash(private_key.xmss_parameters()),
25 m_randomness(0),
26 m_leaf_idx(0),
27 m_is_initialized(false) {}
28
29XMSS_Signature::TreeSignature XMSS_Signature_Operation::generate_tree_signature(const secure_vector<uint8_t>& msg,
30 XMSS_PrivateKey& xmss_priv_key,
31 XMSS_Address& adrs) {
33
34 result.authentication_path = build_auth_path(xmss_priv_key, adrs);
36 adrs.set_ots_address(m_leaf_idx);
37
38 result.ots_signature =
39 xmss_priv_key.wots_private_key_for(adrs, m_hash).sign(msg, xmss_priv_key.public_seed(), adrs, m_hash);
40
41 return result;
42}
43
44XMSS_Signature XMSS_Signature_Operation::sign(const secure_vector<uint8_t>& msg_hash, XMSS_PrivateKey& xmss_priv_key) {
45 XMSS_Address adrs;
46 XMSS_Signature sig(m_leaf_idx, m_randomness, generate_tree_signature(msg_hash, xmss_priv_key, adrs));
47 return sig;
48}
49
51 const auto& params = m_priv_key.xmss_parameters();
52 return sizeof(uint64_t) + // size of leaf index
53 params.element_size() + params.len() * params.element_size() + params.tree_height() * params.element_size();
54}
55
56wots_keysig_t XMSS_Signature_Operation::build_auth_path(XMSS_PrivateKey& priv_key, XMSS_Address& adrs) {
57 const auto& params = m_priv_key.xmss_parameters();
58 wots_keysig_t auth_path(params.tree_height());
60
61 for(size_t j = 0; j < params.tree_height(); j++) {
62 size_t k = (m_leaf_idx / (static_cast<size_t>(1) << j)) ^ 0x01;
63 auth_path[j] = priv_key.tree_hash(k * (static_cast<size_t>(1) << j), j, adrs);
64 }
65
66 return auth_path;
67}
68
69void XMSS_Signature_Operation::update(std::span<const uint8_t> input) {
70 initialize();
71 m_hash.h_msg_update(input);
72}
73
75 initialize();
76 auto sig = sign(m_hash.h_msg_final(), m_priv_key).bytes();
77 m_is_initialized = false;
78 return sig;
79}
80
81void XMSS_Signature_Operation::initialize() {
82 // return if we already initialized and reserved a leaf index for signing.
83 if(m_is_initialized) {
84 return;
85 }
86
87 secure_vector<uint8_t> index_bytes;
88 // reserve leaf index so it can not be reused by another signature
89 // operation using the same private key.
90 m_leaf_idx = static_cast<uint32_t>(m_priv_key.reserve_unused_leaf_index());
91
92 // write prefix for message hashing into buffer.
93 XMSS_Tools::concat(index_bytes, m_leaf_idx, 32);
94 m_hash.prf(m_randomness, m_priv_key.prf_value(), index_bytes);
95 index_bytes.clear();
96 XMSS_Tools::concat(index_bytes, m_leaf_idx, m_priv_key.xmss_parameters().element_size());
97 m_hash.h_msg_init(m_randomness, m_priv_key.root(), index_bytes);
98 m_is_initialized = true;
99}
100
104
105} // 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)
secure_vector< uint8_t > h_msg_final()
Definition xmss_hash.cpp:49
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_update(std::span< const uint8_t > data)
Definition xmss_hash.cpp:45
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:34
size_t element_size() const
const secure_vector< uint8_t > & root() const
Definition xmss.h:118
const secure_vector< uint8_t > & public_seed() const
Definition xmss.h:116
const XMSS_Parameters & xmss_parameters() const
Definition xmss.h:120
XMSS_Signature_Operation(const XMSS_PrivateKey &private_key)
AlgorithmIdentifier algorithm_identifier() const override
std::vector< uint8_t > sign(RandomNumberGenerator &) override
void update(std::span< const uint8_t > input) override
static void concat(secure_vector< uint8_t > &target, const T &src)
Definition xmss_tools.h:54
wots_keysig_t sign(const secure_vector< uint8_t > &msg, std::span< const uint8_t > public_seed, XMSS_Address &adrs, XMSS_Hash &hash)
std::vector< secure_vector< uint8_t > > wots_keysig_t
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61