Botan 2.19.3
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 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 **/
7
8#ifndef BOTAN_XMSS_ADDRESS_H_
9#define BOTAN_XMSS_ADDRESS_H_
10
11#include <botan/types.h>
12
13namespace Botan {
14
15/**
16 * Generic XMSS Address type holding 256 Bits of data. Properties
17 * of all three address formats L-Tree-Address, Hash-Tree-Address,
18 * OTS-Hash-Address can be called depending on the type currently
19 * assigned to the XMSS address using set_type().
20 **/
22 {
23 public:
24 /**
25 * Distinct types an XMSS_Address can represent. The available types
26 * are specified in [1] - 2.5 Hash Function Address Scheme.
27 **/
28 enum class Type : uint8_t
29 {
30 None = 255,
32 LTree_Address = 1,
34 };
35
36 /**
37 * The available modes for an XMSS Address:
38 * - Key_Mode: Used to generate the key.
39 * - Mask_Mode: Sets the n-byte bitmask (OTS-Hash-Address)
40 * - Mask_MSB_Mode: Used to generate the b most significant bytes of
41 * the 2n-byte bitmask (LTree Address and Hash Tree Address).
42 * - Mask_LSB_Mode: Used to generated the b least significant bytes
43 * of the 2n-byte bitmask. (LTree Address and Hash Tree Address).
44 **/
45 enum class Key_Mask : uint8_t
46 {
47 Key_Mode = 0,
48 Mask_Mode = 1,
49 Mask_MSB_Mode = 1,
51 };
52
53 /**
54 * Layer Address for XMSS is constantly zero and can not be changed this
55 * property is only of relevance to XMSS_MT.
56 *
57 * @return Layer address, which is constant 0 for XMSS.
58 **/
59 uint8_t get_layer_addr() const { return 0; }
60
61 /**
62 * Layer Address for XMSS is constantly zero and can not be changed this
63 * property is only of relevance to XMSS_MT. Calling this method for
64 * XMSS will result in an error.
65 **/
67 {
68 BOTAN_ASSERT(false, "Only available in XMSS_MT.");
69 }
70
71 /**
72 * Tree Address for XMSS is constantly zero and can not be changed this
73 * property is only of relevance to XMSS_MT.
74 *
75 * @return Tree address, which is constant 0 for XMSS.
76 **/
77 uint64_t get_tree_addr() const { return 0; }
78
79 /**
80 * Tree Address for XMSS is constantly zero and can not be changed this
81 * property is only of relevance to XMSS_MT. Calling this method for
82 * XMSS will result in an error.
83 **/
85 {
86 BOTAN_ASSERT(false, "Only available in XMSS_MT.");
87 }
88
89 /**
90 * retrieves the logical type currently assigned to the XMSS Address
91 * instance.
92 *
93 * @return Type of the address (OTS_Hash_Address, LTree_Address or
94 * Hash_Tree_Address)
95 **/
96 Type get_type() const
97 {
98 return static_cast<Type>(m_data[15]);
99 }
100
101 /**
102 * Changes the logical type currently assigned to the XMSS Address
103 * instance. Please note that changing the type will automatically
104 * reset the 128 LSBs of the Address to zero. This affects the
105 * key_mask_mode property as well as all properties identified by
106 * XMSS_Address::Property.
107 *
108 * @param type Type that shall be assigned to the address
109 * (OTS_Hash_Address, LTree_Address or Hash_Tree_Address)
110 **/
112 {
113 m_data[15] = static_cast<uint8_t>(type);
114 std::fill(m_data.begin() + 16, m_data.end(), static_cast<uint8_t>(0));
115 }
116
117 /**
118 * Retrieves the mode the address os currently set to. (See
119 * XMSS_Address::Key_Mask for details.)
120 *
121 * @return currently active mode
122 **/
124 {
125 return Key_Mask(m_data[31]);
126 }
127
128 /**
129 * Changes the mode the address currently used address mode.
130 * (XMSS_Address::Key_Mask for details.)
131 *
132 * @param value Target mode.
133 **/
135 {
138 "Invalid Key_Mask for current XMSS_Address::Type.");
139 m_data[31] = static_cast<uint8_t>(value);
140 }
141
142 /**
143 * Retrieve the index of the OTS key pair within the tree. A call to
144 * this method is only valid, if the address type is set to
145 * Type::OTS_Hash_Address.
146 *
147 * @return index of OTS key pair.
148 **/
149 uint32_t get_ots_address() const
150 {
152 "get_ots_address() requires XMSS_Address::Type::"
153 "OTS_Hash_Address.");
154 return get_hi32(2);
155 }
156
157 /**
158 * Sets the index of the OTS key pair within the tree. A call to this
159 * method is only valid, if the address type is set to
160 * Type::OTS_Hash_Address.
161 *
162 * @param value index of OTS key pair.
163 **/
164 void set_ots_address(uint32_t value)
165 {
167 "set_ots_address() requires XMSS_Address::Type::"
168 "OTS_Hash_Address.");
169 set_hi32(2, value);
170 }
171
172 /**
173 * Retrieves the index of the leaf computed with this LTree. A call to
174 * this method is only valid, if the address type is set to
175 * Type::LTree_Address.
176 *
177 * @return index of the leaf.
178 **/
179 uint32_t get_ltree_address() const
180 {
182 "set_ltree_address() requires XMSS_Address::Type::"
183 "LTree_Address.");
184 return get_hi32(2);
185 }
186
187 /**
188 * Sets the index of the leaf computed with this LTree. A call to this
189 * method is only valid, if the address type is set to
190 * Type::LTree_Address.
191 *
192 * @param value index of the leaf.
193 **/
194 void set_ltree_address(uint32_t value)
195 {
197 "set_ltree_address() requires XMSS_Address::Type::"
198 "LTree_Address.");
199 set_hi32(2, value);
200 }
201
202 /**
203 * Retrieve the chain address. A call to this method is only valid, if
204 * the address type is set to Type::OTS_Hash_Address.
205 *
206 * @return chain address.
207 **/
208 uint32_t get_chain_address() const
209 {
211 "get_chain_address() requires XMSS_Address::Type::"
212 "OTS_Hash_Address.");
213 return get_lo32(2);
214 }
215
216 /**
217 * Set the chain address. A call to this method is only valid, if
218 * the address type is set to Type::OTS_Hash_Address.
219 **/
220 void set_chain_address(uint32_t value)
221 {
223 "set_chain_address() requires XMSS_Address::Type::"
224 "OTS_Hash_Address.");
225 set_lo32(2, value);
226 }
227
228 /**
229 * Retrieves the height of the tree node to be computed within the
230 * tree. A call to this method is only valid, if the address type is
231 * set to Type::LTree_Address or Type::Hash_Tree_Address.
232 *
233 * @return height of the tree node.
234 **/
235 uint32_t get_tree_height() const
236 {
239 "get_tree_height() requires XMSS_Address::Type::"
240 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
241 return get_lo32(2);
242 }
243
244 /**
245 * Sets the height of the tree node to be computed within the
246 * tree. A call to this method is only valid, if the address type is
247 * set to Type::LTree_Address or Type::Hash_Tree_Address.
248 *
249 * @param value height of the tree node.
250 **/
251 void set_tree_height(uint32_t value)
252 {
255 "set_tree_height() requires XMSS_Address::Type::"
256 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
257 set_lo32(2, value);
258 }
259
260 /**
261 * Retrieves the address of the hash function call within the chain.
262 * A call to this method is only valid, if the address type is
263 * set to Type::OTS_Hash_Address.
264 *
265 * @return address of the hash function call within chain.
266 **/
267 uint32_t get_hash_address() const
268 {
270 "get_hash_address() requires XMSS_Address::Type::"
271 "OTS_Hash_Address.");
272 return get_hi32(3);
273 }
274
275 /**
276 * Sets the address of the hash function call within the chain.
277 * A call to this method is only valid, if the address type is
278 * set to Type::OTS_Hash_Address.
279 *
280 * @param value address of the hash function call within chain.
281 **/
282 void set_hash_address(uint32_t value)
283 {
285 "set_hash_address() requires XMSS_Address::Type::"
286 "OTS_Hash_Address.");
287 set_hi32(3, value);
288 }
289
290 /**
291 * Retrieves the index of the tree node at current tree height in the
292 * tree. A call to this method is only valid, if the address type is
293 * set to Type::LTree_Address or Type::Hash_Tree_Address.
294 *
295 * @return index of the tree node at current height.
296 **/
297 uint32_t get_tree_index() const
298 {
301 "get_tree_index() requires XMSS_Address::Type::"
302 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
303 return get_hi32(3);
304 }
305
306 /**
307 * Sets the index of the tree node at current tree height in the
308 * tree. A call to this method is only valid, if the address type is
309 * set to Type::LTree_Address or Type::Hash_Tree_Address.
310 *
311 * @param value index of the tree node at current height.
312 **/
313 void set_tree_index(uint32_t value)
314 {
317 "set_tree_index() requires XMSS_Address::Type::"
318 "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
319 set_hi32(3, value);
320 }
321
323 {
324 return m_data;
325 }
326
328 {
329 return m_data;
330 }
331
332 /**
333 * @return the size of an XMSS_Address
334 **/
335 size_t size() const
336 {
337 return m_data.size();
338 }
339
341 : m_data(m_address_size)
342 {
344 }
345
347 : m_data(m_address_size)
348 {
349 set_type(type);
350 }
351
353 {
354 BOTAN_ASSERT(m_data.size() == m_address_size,
355 "XMSS_Address must be of 256 bits size.");
356 }
357
359 {
360 BOTAN_ASSERT(m_data.size() == m_address_size,
361 "XMSS_Address must be of 256 bits size.");
362 }
363
364 protected:
366
367 private:
368 static const size_t m_address_size = 32;
369
370 inline uint32_t get_hi32(size_t offset) const
371 {
372 return ((0x000000FF & m_data[8 * offset + 3]) |
373 (0x000000FF & m_data[8 * offset + 2]) << 8 |
374 (0x000000FF & m_data[8 * offset + 1]) << 16 |
375 (0x000000FF & m_data[8 * offset ]) << 24);
376 }
377
378 inline void set_hi32(size_t offset, uint32_t value)
379 {
380 m_data[offset * 8 ] = ((value >> 24) & 0xFF);
381 m_data[offset * 8 + 1] = ((value >> 16) & 0xFF);
382 m_data[offset * 8 + 2] = ((value >> 8) & 0xFF);
383 m_data[offset * 8 + 3] = ((value ) & 0xFF);
384 }
385
386 inline uint32_t get_lo32(size_t offset) const
387 {
388 return ((0x000000FF & m_data[8 * offset + 7]) |
389 (0x000000FF & m_data[8 * offset + 6]) << 8 |
390 (0x000000FF & m_data[8 * offset + 5]) << 16 |
391 (0x000000FF & m_data[8 * offset + 4]) << 24);
392 }
393
394 inline void set_lo32(size_t offset, uint32_t value)
395 {
396 m_data[offset * 8 + 4] = ((value >> 24) & 0xFF);
397 m_data[offset * 8 + 5] = ((value >> 16) & 0xFF);
398 m_data[offset * 8 + 6] = ((value >> 8) & 0xFF);
399 m_data[offset * 8 + 7] = ((value ) & 0xFF);
400 }
401 };
402
403}
404
405#endif
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:55
XMSS_Address(secure_vector< uint8_t > &&data)
void set_hash_address(uint32_t value)
void set_key_mask_mode(Key_Mask value)
secure_vector< uint8_t > m_data
void set_ots_address(uint32_t value)
Type get_type() const
size_t size() const
uint32_t get_tree_index() const
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)
uint64_t get_tree_addr() const
uint8_t get_layer_addr() const
XMSS_Address(const secure_vector< uint8_t > &data)
XMSS_Address(Type type)
uint32_t get_chain_address() const
const secure_vector< uint8_t > & bytes() const
secure_vector< uint8_t > & bytes()
void set_ltree_address(uint32_t value)
uint32_t get_hash_address() const
Key_Mask get_key_mask_mode() const
int(* final)(unsigned char *, CTX *)
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:65
Definition bigint.h:1143
MechanismType type