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