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