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