Coverage Report

Created: 2024-11-29 06:10

/src/botan/src/lib/pubkey/xmss/xmss_signature_operation.cpp
Line
Count
Source (jump to first uncovered line)
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
20
namespace Botan {
21
22
XMSS_Signature_Operation::XMSS_Signature_Operation(const XMSS_PrivateKey& private_key) :
23
0
      m_priv_key(private_key),
24
0
      m_hash(private_key.xmss_parameters()),
25
0
      m_randomness(0),
26
0
      m_leaf_idx(0),
27
0
      m_is_initialized(false) {}
Unexecuted instantiation: Botan::XMSS_Signature_Operation::XMSS_Signature_Operation(Botan::XMSS_PrivateKey const&)
Unexecuted instantiation: Botan::XMSS_Signature_Operation::XMSS_Signature_Operation(Botan::XMSS_PrivateKey const&)
28
29
XMSS_Signature::TreeSignature XMSS_Signature_Operation::generate_tree_signature(const secure_vector<uint8_t>& msg,
30
                                                                                XMSS_PrivateKey& xmss_priv_key,
31
0
                                                                                XMSS_Address& adrs) {
32
0
   XMSS_Signature::TreeSignature result;
33
34
0
   result.authentication_path = build_auth_path(xmss_priv_key, adrs);
35
0
   adrs.set_type(XMSS_Address::Type::OTS_Hash_Address);
36
0
   adrs.set_ots_address(m_leaf_idx);
37
38
0
   result.ots_signature =
39
0
      xmss_priv_key.wots_private_key_for(adrs, m_hash).sign(msg, xmss_priv_key.public_seed(), adrs, m_hash);
40
41
0
   return result;
42
0
}
43
44
0
XMSS_Signature XMSS_Signature_Operation::sign(const secure_vector<uint8_t>& msg_hash, XMSS_PrivateKey& xmss_priv_key) {
45
0
   XMSS_Address adrs;
46
0
   XMSS_Signature sig(m_leaf_idx, m_randomness, generate_tree_signature(msg_hash, xmss_priv_key, adrs));
47
0
   return sig;
48
0
}
49
50
0
size_t XMSS_Signature_Operation::signature_length() const {
51
0
   const auto& params = m_priv_key.xmss_parameters();
52
0
   return sizeof(uint64_t) +  // size of leaf index
53
0
          params.element_size() + params.len() * params.element_size() + params.tree_height() * params.element_size();
54
0
}
55
56
0
wots_keysig_t XMSS_Signature_Operation::build_auth_path(XMSS_PrivateKey& priv_key, XMSS_Address& adrs) {
57
0
   const auto& params = m_priv_key.xmss_parameters();
58
0
   wots_keysig_t auth_path(params.tree_height());
59
0
   adrs.set_type(XMSS_Address::Type::Hash_Tree_Address);
60
61
0
   for(size_t j = 0; j < params.tree_height(); j++) {
62
0
      size_t k = (m_leaf_idx / (static_cast<size_t>(1) << j)) ^ 0x01;
63
0
      auth_path[j] = priv_key.tree_hash(k * (static_cast<size_t>(1) << j), j, adrs);
64
0
   }
65
66
0
   return auth_path;
67
0
}
68
69
0
void XMSS_Signature_Operation::update(std::span<const uint8_t> input) {
70
0
   initialize();
71
0
   m_hash.h_msg_update(input);
72
0
}
73
74
0
std::vector<uint8_t> XMSS_Signature_Operation::sign(RandomNumberGenerator& /*rng*/) {
75
0
   initialize();
76
0
   auto sig = sign(m_hash.h_msg_final(), m_priv_key).bytes();
77
0
   m_is_initialized = false;
78
0
   return sig;
79
0
}
80
81
0
void XMSS_Signature_Operation::initialize() {
82
   // return if we already initialized and reserved a leaf index for signing.
83
0
   if(m_is_initialized) {
84
0
      return;
85
0
   }
86
87
0
   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
0
   m_leaf_idx = static_cast<uint32_t>(m_priv_key.reserve_unused_leaf_index());
91
92
   // write prefix for message hashing into buffer.
93
0
   XMSS_Tools::concat(index_bytes, m_leaf_idx, 32);
94
0
   m_hash.prf(m_randomness, m_priv_key.prf_value(), index_bytes);
95
0
   index_bytes.clear();
96
0
   XMSS_Tools::concat(index_bytes, m_leaf_idx, m_priv_key.xmss_parameters().element_size());
97
0
   m_hash.h_msg_init(m_randomness, m_priv_key.root(), index_bytes);
98
0
   m_is_initialized = true;
99
0
}
100
101
0
AlgorithmIdentifier XMSS_Signature_Operation::algorithm_identifier() const {
102
0
   return AlgorithmIdentifier(OID::from_string("XMSS"), AlgorithmIdentifier::USE_EMPTY_PARAM);
103
0
}
104
105
}  // namespace Botan