Coverage Report

Created: 2019-12-03 15:21

/src/botan/build/include/botan/xmss_address.h
Line
Count
Source (jump to first uncovered line)
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/xmss_tools.h>
12
13
namespace 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
 **/
21
class XMSS_Address final
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,
31
         OTS_Hash_Address = 0,
32
         LTree_Address = 1,
33
         Hash_Tree_Address = 2
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,
50
         Mask_LSB_Mode = 2
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
0
      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
       **/
66
      void set_layer_addr()
67
0
         {
68
0
         BOTAN_ASSERT(false, "Only available in XMSS_MT.");
69
0
         }
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
0
      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
       **/
84
      void set_tree_addr()
85
0
         {
86
0
         BOTAN_ASSERT(false, "Only available in XMSS_MT.");
87
0
         }
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
0
         {
98
0
         return static_cast<Type>(m_data[15]);
99
0
         }
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
       **/
111
      void set_type(Type type)
112
0
         {
113
0
         m_data[15] = static_cast<uint8_t>(type);
114
0
         std::fill(m_data.begin() + 16, m_data.end(), static_cast<uint8_t>(0));
115
0
         }
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
       **/
123
      Key_Mask get_key_mask_mode() const
124
0
         {
125
0
         return Key_Mask(m_data[31]);
126
0
         }
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
       **/
134
      void set_key_mask_mode(Key_Mask value)
135
0
         {
136
0
         BOTAN_ASSERT(value != Key_Mask::Mask_LSB_Mode ||
137
0
                      get_type() != Type::OTS_Hash_Address,
138
0
                      "Invalid Key_Mask for current XMSS_Address::Type.");
139
0
         m_data[31] = static_cast<uint8_t>(value);
140
0
         }
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
0
         {
151
0
         BOTAN_ASSERT(get_type() == Type::OTS_Hash_Address,
152
0
                      "get_ots_address() requires XMSS_Address::Type::"
153
0
                      "OTS_Hash_Address.");
154
0
         return get_hi32(2);
155
0
         }
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
0
         {
166
0
         BOTAN_ASSERT(get_type() == Type::OTS_Hash_Address,
167
0
                      "set_ots_address() requires XMSS_Address::Type::"
168
0
                      "OTS_Hash_Address.");
169
0
         set_hi32(2, value);
170
0
         }
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
0
         {
181
0
         BOTAN_ASSERT(get_type() == Type::LTree_Address,
182
0
                      "set_ltree_address() requires XMSS_Address::Type::"
183
0
                      "LTree_Address.");
184
0
         return get_hi32(2);
185
0
         }
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
0
         {
196
0
         BOTAN_ASSERT(get_type() == Type::LTree_Address,
197
0
                      "set_ltree_address() requires XMSS_Address::Type::"
198
0
                      "LTree_Address.");
199
0
         set_hi32(2, value);
200
0
         }
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
0
         {
210
0
         BOTAN_ASSERT(get_type() == Type::OTS_Hash_Address,
211
0
                      "get_chain_address() requires XMSS_Address::Type::"
212
0
                      "OTS_Hash_Address.");
213
0
         return get_lo32(2);
214
0
         }
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
0
         {
222
0
         BOTAN_ASSERT(get_type() == Type::OTS_Hash_Address,
223
0
                      "set_chain_address() requires XMSS_Address::Type::"
224
0
                      "OTS_Hash_Address.");
225
0
         set_lo32(2, value);
226
0
         }
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
0
         {
237
0
         BOTAN_ASSERT(get_type() == Type::LTree_Address ||
238
0
                      get_type() == Type::Hash_Tree_Address,
239
0
                      "get_tree_height() requires XMSS_Address::Type::"
240
0
                      "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
241
0
         return get_lo32(2);
242
0
         }
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
0
         {
253
0
         BOTAN_ASSERT(get_type() == Type::LTree_Address ||
254
0
                      get_type() == Type::Hash_Tree_Address,
255
0
                      "set_tree_height() requires XMSS_Address::Type::"
256
0
                      "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
257
0
         set_lo32(2, value);
258
0
         }
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
0
         {
269
0
         BOTAN_ASSERT(get_type() == Type::OTS_Hash_Address,
270
0
                      "get_hash_address() requires XMSS_Address::Type::"
271
0
                      "OTS_Hash_Address.");
272
0
         return get_hi32(3);
273
0
         }
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
0
         {
284
0
         BOTAN_ASSERT(get_type() == Type::OTS_Hash_Address,
285
0
                      "set_hash_address() requires XMSS_Address::Type::"
286
0
                      "OTS_Hash_Address.");
287
0
         set_hi32(3, value);
288
0
         }
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
0
         {
299
0
         BOTAN_ASSERT(get_type() == Type::LTree_Address ||
300
0
                      get_type() == Type::Hash_Tree_Address,
301
0
                      "get_tree_index() requires XMSS_Address::Type::"
302
0
                      "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
303
0
         return get_hi32(3);
304
0
         }
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
0
         {
315
0
         BOTAN_ASSERT(get_type() == Type::LTree_Address ||
316
0
                      get_type() == Type::Hash_Tree_Address,
317
0
                      "set_tree_index() requires XMSS_Address::Type::"
318
0
                      "LTree_Address or XMSS_Address::Type::Hash_Tree_Address.");
319
0
         set_hi32(3, value);
320
0
         }
321
322
      const secure_vector<uint8_t>& bytes() const
323
0
         {
324
0
         return m_data;
325
0
         }
326
327
      secure_vector<uint8_t>& bytes()
328
0
         {
329
0
         return m_data;
330
0
         }
331
332
      /**
333
       * @return the size of an XMSS_Address
334
       **/
335
      size_t size() const
336
0
         {
337
0
         return m_data.size();
338
0
         }
339
340
      XMSS_Address()
341
         : m_data(m_address_size)
342
0
         {
343
0
         set_type(Type::None);
344
0
         }
345
346
      XMSS_Address(Type type)
347
         : m_data(m_address_size)
348
0
         {
349
0
         set_type(type);
350
0
         }
351
352
      XMSS_Address(const secure_vector<uint8_t>& data) : m_data(data)
353
0
         {
354
0
         BOTAN_ASSERT(m_data.size() == m_address_size,
355
0
                      "XMSS_Address must be of 256 bits size.");
356
0
         }
357
358
      XMSS_Address(secure_vector<uint8_t>&& data) : m_data(std::move(data))
359
0
         {
360
0
         BOTAN_ASSERT(m_data.size() == m_address_size,
361
0
                      "XMSS_Address must be of 256 bits size.");
362
0
         }
363
364
   protected:
365
      secure_vector<uint8_t> m_data;
366
367
   private:
368
      static const size_t m_address_size = 32;
369
370
      inline uint32_t get_hi32(size_t offset) const
371
0
         {
372
0
         return ((0x000000FF & m_data[8 * offset + 3])       |
373
0
                 (0x000000FF & m_data[8 * offset + 2]) <<  8 |
374
0
                 (0x000000FF & m_data[8 * offset + 1]) << 16 |
375
0
                 (0x000000FF & m_data[8 * offset    ]) << 24);
376
0
         }
377
378
      inline void set_hi32(size_t offset, uint32_t value)
379
0
         {
380
0
         m_data[offset * 8    ] = ((value >> 24) & 0xFF);
381
0
         m_data[offset * 8 + 1] = ((value >> 16) & 0xFF);
382
0
         m_data[offset * 8 + 2] = ((value >>  8) & 0xFF);
383
0
         m_data[offset * 8 + 3] = ((value      ) & 0xFF);
384
0
         }
385
386
      inline uint32_t get_lo32(size_t offset) const
387
0
         {
388
0
         return ((0x000000FF & m_data[8 * offset + 7])       |
389
0
                 (0x000000FF & m_data[8 * offset + 6]) <<  8 |
390
0
                 (0x000000FF & m_data[8 * offset + 5]) << 16 |
391
0
                 (0x000000FF & m_data[8 * offset + 4]) << 24);
392
0
         }
393
394
      inline void set_lo32(size_t offset, uint32_t value)
395
0
         {
396
0
         m_data[offset * 8 + 4] = ((value >> 24) & 0xFF);
397
0
         m_data[offset * 8 + 5] = ((value >> 16) & 0xFF);
398
0
         m_data[offset * 8 + 6] = ((value >>  8) & 0xFF);
399
0
         m_data[offset * 8 + 7] = ((value      ) & 0xFF);
400
0
         }
401
   };
402
403
}
404
405
#endif