Botan 3.11.0
Crypto and TLS for C&
xmss_address.h
Go to the documentation of this file.
1/*
2 * XMSS Address
3 * (C) 2016 Matthias Gierlings
4 * 2026 Jack Lloyd
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 **/
8
9#ifndef BOTAN_XMSS_ADDRESS_H_
10#define BOTAN_XMSS_ADDRESS_H_
11
12#include <botan/assert.h>
13#include <botan/types.h>
14#include <array>
15#include <span>
16
17namespace Botan {
18
19/**
20 * Generic XMSS Address type holding 256 Bits of data. Properties
21 * of all three address formats L-Tree-Address, Hash-Tree-Address,
22 * OTS-Hash-Address can be called depending on the type currently
23 * assigned to the XMSS address using set_type().
24 **/
25class XMSS_Address final {
26 public:
27 /**
28 * Distinct types an XMSS_Address can represent. The available types
29 * are specified in [1] - 2.5 Hash Function Address Scheme.
30 **/
31 enum class Type : uint8_t { None = 255, OTS_Hash_Address = 0, LTree_Address = 1, Hash_Tree_Address = 2 };
32
33 /**
34 * The available modes for an XMSS Address:
35 * - Key_Mode: Used to generate the key.
36 * - Mask_Mode: Sets the n-byte bitmask (OTS-Hash-Address)
37 * - Mask_MSB_Mode: Used to generate the b most significant bytes of
38 * the 2n-byte bitmask (LTree Address and Hash Tree Address).
39 * - Mask_LSB_Mode: Used to generated the b least significant bytes
40 * of the 2n-byte bitmask. (LTree Address and Hash Tree Address).
41 **/
42 enum class Key_Mask : uint8_t { Key_Mode = 0, Mask_Mode = 1, Mask_MSB_Mode = 1, Mask_LSB_Mode = 2 };
43
44 /**
45 * Layer Address for XMSS is constantly zero and can not be changed this
46 * property is only of relevance to XMSS_MT.
47 *
48 * @return Layer address, which is constant 0 for XMSS.
49 **/
50 uint8_t get_layer_addr() const { return 0; }
51
52 /**
53 * Layer Address for XMSS is constantly zero and can not be changed this
54 * property is only of relevance to XMSS_MT. Calling this method for
55 * XMSS will result in an error.
56 **/
57 void set_layer_addr() { BOTAN_ASSERT(false, "Only available in XMSS_MT."); }
58
59 /**
60 * Tree Address for XMSS is constantly zero and can not be changed this
61 * property is only of relevance to XMSS_MT.
62 *
63 * @return Tree address, which is constant 0 for XMSS.
64 **/
65 uint64_t get_tree_addr() const { return 0; }
66
67 /**
68 * Tree Address for XMSS is constantly zero and can not be changed this
69 * property is only of relevance to XMSS_MT. Calling this method for
70 * XMSS will result in an error.
71 **/
72 void set_tree_addr() { BOTAN_ASSERT(false, "Only available in XMSS_MT."); }
73
74 /**
75 * retrieves the logical type currently assigned to the XMSS Address
76 * instance.
77 *
78 * @return Type of the address (OTS_Hash_Address, LTree_Address or
79 * Hash_Tree_Address)
80 **/
81 Type get_type() const { return static_cast<Type>(m_data[15]); }
82
83 /**
84 * Changes the logical type currently assigned to the XMSS Address
85 * instance. Please note that changing the type will automatically
86 * reset the 128 LSBs of the Address to zero. This affects the
87 * key_mask_mode property as well as all properties identified by
88 * XMSS_Address::Property.
89 *
90 * @param type Type that shall be assigned to the address
91 * (OTS_Hash_Address, LTree_Address or Hash_Tree_Address)
92 **/
93 void set_type(Type type) {
94 m_data[15] = static_cast<uint8_t>(type);
95 std::fill(m_data.begin() + 16, m_data.end(), static_cast<uint8_t>(0));
96 }
97
98 /**
99 * Retrieves the mode the address is currently set to. (See
100 * XMSS_Address::Key_Mask for details.)
101 *
102 * @return currently active mode
103 **/
104 Key_Mask get_key_mask_mode() const { return Key_Mask(m_data[31]); }
105
106 /**
107 * Changes the mode the address currently used address mode.
108 * (XMSS_Address::Key_Mask for details.)
109 *
110 * @param value Target mode.
111 **/
114 "Invalid Key_Mask for current XMSS_Address::Type.");
115 m_data[31] = static_cast<uint8_t>(value);
116 }
117
118 /**
119 * Retrieve the index of the OTS key pair within the tree. A call to
120 * this method is only valid, if the address type is set to
121 * Type::OTS_Hash_Address.
122 *
123 * @return index of OTS key pair.
124 **/
125 uint32_t get_ots_address() const {
127 "get_ots_address() requires XMSS_Address::Type::"
128 "OTS_Hash_Address.");
129 return get_hi32(2);
130 }
131
132 /**
133 * Sets the index of the OTS key pair within the tree. A call to this
134 * method is only valid, if the address type is set to
135 * Type::OTS_Hash_Address.
136 *
137 * @param value index of OTS key pair.
138 **/
139 void set_ots_address(uint32_t value) {
141 "set_ots_address() requires XMSS_Address::Type::"
142 "OTS_Hash_Address.");
143 set_hi32(2, value);
144 }
145
146 /**
147 * Retrieves the index of the leaf computed with this LTree. A call to
148 * this method is only valid, if the address type is set to
149 * Type::LTree_Address.
150 *
151 * @return index of the leaf.
152 **/
153 uint32_t get_ltree_address() const {
155 "set_ltree_address() requires XMSS_Address::Type::"
156 "LTree_Address.");
157 return get_hi32(2);
158 }
159
160 /**
161 * Sets the index of the leaf computed with this LTree. A call to this
162 * method is only valid, if the address type is set to
163 * Type::LTree_Address.
164 *
165 * @param value index of the leaf.
166 **/
167 void set_ltree_address(uint32_t value) {
169 "set_ltree_address() requires XMSS_Address::Type::"
170 "LTree_Address.");
171 set_hi32(2, value);
172 }
173
174 /**
175 * Retrieve the chain address. A call to this method is only valid, if
176 * the address type is set to Type::OTS_Hash_Address.
177 *
178 * @return chain address.
179 **/
180 uint32_t get_chain_address() const {
182 "get_chain_address() requires XMSS_Address::Type::"
183 "OTS_Hash_Address.");
184 return get_lo32(2);
185 }
186
187 /**
188 * Set the chain address. A call to this method is only valid, if
189 * the address type is set to Type::OTS_Hash_Address.
190 **/
191 void set_chain_address(uint32_t value) {
193 "set_chain_address() requires XMSS_Address::Type::"
194 "OTS_Hash_Address.");
195 set_lo32(2, value);
196 }
197
198 /**
199 * Retrieves the height of the tree node to be computed within the
200 * tree. A call to this method is only valid, if the address type is
201 * set to Type::LTree_Address or Type::Hash_Tree_Address.
202 *
203 * @return height of the tree node.
204 **/
205 uint32_t get_tree_height() const {
207 "get_tree_height() requires XMSS_Address::Type::"
208 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
209 return get_lo32(2);
210 }
211
212 /**
213 * Sets the height of the tree node to be computed within the
214 * tree. A call to this method is only valid, if the address type is
215 * set to Type::LTree_Address or Type::Hash_Tree_Address.
216 *
217 * @param value height of the tree node.
218 **/
219 void set_tree_height(uint32_t value) {
221 "set_tree_height() requires XMSS_Address::Type::"
222 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
223 set_lo32(2, value);
224 }
225
226 /**
227 * Retrieves the address of the hash function call within the chain.
228 * A call to this method is only valid, if the address type is
229 * set to Type::OTS_Hash_Address.
230 *
231 * @return address of the hash function call within chain.
232 **/
233 uint32_t get_hash_address() const {
235 "get_hash_address() requires XMSS_Address::Type::"
236 "OTS_Hash_Address.");
237 return get_hi32(3);
238 }
239
240 /**
241 * Sets the address of the hash function call within the chain.
242 * A call to this method is only valid, if the address type is
243 * set to Type::OTS_Hash_Address.
244 *
245 * @param value address of the hash function call within chain.
246 **/
247 void set_hash_address(uint32_t value) {
249 "set_hash_address() requires XMSS_Address::Type::"
250 "OTS_Hash_Address.");
251 set_hi32(3, value);
252 }
253
254 /**
255 * Retrieves the index of the tree node at current tree height in the
256 * tree. A call to this method is only valid, if the address type is
257 * set to Type::LTree_Address or Type::Hash_Tree_Address.
258 *
259 * @return index of the tree node at current height.
260 **/
261 uint32_t get_tree_index() const {
263 "get_tree_index() requires XMSS_Address::Type::"
264 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
265 return get_hi32(3);
266 }
267
268 /**
269 * Sets the index of the tree node at current tree height in the
270 * tree. A call to this method is only valid, if the address type is
271 * set to Type::LTree_Address or Type::Hash_Tree_Address.
272 *
273 * @param value index of the tree node at current height.
274 **/
275 void set_tree_index(uint32_t value) {
277 "set_tree_index() requires XMSS_Address::Type::"
278 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
279 set_hi32(3, value);
280 }
281
282 std::span<const uint8_t> bytes() const { return std::span{m_data}; }
283
284 /**
285 * @return the size of an XMSS_Address
286 **/
287 size_t size() const { return m_data.size(); }
288
290
291 ~XMSS_Address() = default;
292 XMSS_Address(const XMSS_Address& other) = default;
293 XMSS_Address(XMSS_Address&& other) = default;
294
295 XMSS_Address& operator=(const XMSS_Address& other) = default;
297
298 explicit XMSS_Address(Type type) : m_data() { set_type(type); }
299
300 private:
301 inline uint32_t get_hi32(size_t offset) const {
302 return ((0x000000FF & m_data[8 * offset + 3]) | (0x000000FF & m_data[8 * offset + 2]) << 8 |
303 (0x000000FF & m_data[8 * offset + 1]) << 16 | (0x000000FF & m_data[8 * offset]) << 24);
304 }
305
306 inline void set_hi32(size_t offset, uint32_t value) {
307 m_data[offset * 8] = ((value >> 24) & 0xFF);
308 m_data[offset * 8 + 1] = ((value >> 16) & 0xFF);
309 m_data[offset * 8 + 2] = ((value >> 8) & 0xFF);
310 m_data[offset * 8 + 3] = ((value) & 0xFF);
311 }
312
313 inline uint32_t get_lo32(size_t offset) const {
314 return ((0x000000FF & m_data[8 * offset + 7]) | (0x000000FF & m_data[8 * offset + 6]) << 8 |
315 (0x000000FF & m_data[8 * offset + 5]) << 16 | (0x000000FF & m_data[8 * offset + 4]) << 24);
316 }
317
318 inline void set_lo32(size_t offset, uint32_t value) {
319 m_data[offset * 8 + 4] = ((value >> 24) & 0xFF);
320 m_data[offset * 8 + 5] = ((value >> 16) & 0xFF);
321 m_data[offset * 8 + 6] = ((value >> 8) & 0xFF);
322 m_data[offset * 8 + 7] = ((value) & 0xFF);
323 }
324
325 std::array<uint8_t, 32> m_data; // NOLINT(*non-private-member-variable*)
326};
327
328} // namespace Botan
329
330#endif
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
void set_hash_address(uint32_t value)
void set_key_mask_mode(Key_Mask value)
XMSS_Address(XMSS_Address &&other)=default
void set_ots_address(uint32_t value)
Type get_type() const
size_t size() const
uint32_t get_tree_index() const
XMSS_Address & operator=(XMSS_Address &&other)=default
XMSS_Address & operator=(const XMSS_Address &other)=default
uint32_t get_ots_address() const
void set_type(Type type)
uint32_t get_ltree_address() const
void set_chain_address(uint32_t value)
uint32_t get_tree_height() const
void set_tree_height(uint32_t value)
void set_tree_index(uint32_t value)
std::span< const uint8_t > bytes() const
uint64_t get_tree_addr() const
uint8_t get_layer_addr() const
XMSS_Address(Type type)
XMSS_Address(const XMSS_Address &other)=default
uint32_t get_chain_address() const
~XMSS_Address()=default
void set_ltree_address(uint32_t value)
uint32_t get_hash_address() const
Key_Mask get_key_mask_mode() const