Botan 3.4.0
Crypto and TLS for C&
sp_address.h
Go to the documentation of this file.
1/*
2 * SPHINCS+ Address
3 * (C) 2023 Jack Lloyd
4 * 2023 Fabian Albert, René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 **/
8
9#ifndef BOTAN_SPHINCS_PLUS_ADDRESS_H_
10#define BOTAN_SPHINCS_PLUS_ADDRESS_H_
11
12#include <array>
13
14#include <botan/hash.h>
15#include <botan/internal/loadstor.h>
16#include <botan/internal/sp_types.h>
17
18namespace Botan {
19
20enum class Sphincs_Address_Type : uint32_t {
21 WotsHash = 0,
23 HashTree = 2,
24 ForsTree = 3,
28};
29
30/**
31 * Representation of a SPHINCS+ hash function address as specified in
32 * SPHINCS+ Specification Round 3.1, Section 2.7.3
33 */
35 private:
36 static constexpr size_t layer_offset = 0;
37 static constexpr size_t tree_offset = 1; // tree address is 3 words wide
38 static constexpr size_t type_offset = 4;
39 static constexpr size_t keypair_offset = 5;
40 static constexpr size_t chain_offset = 6;
41 static constexpr size_t hash_offset = 7;
42 static constexpr size_t tree_height_offset = chain_offset;
43 static constexpr size_t tree_index_offset = hash_offset;
44
45 public:
46 using enum Sphincs_Address_Type;
47
49 m_address.fill(0);
50 set_type(type);
51 }
52
53 Sphincs_Address(std::array<uint32_t, 8> address) { std::copy(address.begin(), address.end(), m_address.begin()); }
54
56 m_address[layer_offset] = layer.get();
57 return *this;
58 }
59
61 m_address[tree_offset + 0] = 0; // not required by all current instances
62 m_address[tree_offset + 1] = static_cast<uint32_t>(tree.get() >> 32);
63 m_address[tree_offset + 2] = static_cast<uint32_t>(tree.get());
64 return *this;
65 }
66
68 m_address[type_offset] = static_cast<uint32_t>(type);
69 return *this;
70 }
71
72 /* These functions are used for WOTS and FORS addresses. */
73
75 m_address[keypair_offset] = keypair.get();
76 return *this;
77 }
78
80 m_address[chain_offset] = chain.get();
81 return *this;
82 }
83
85 m_address[hash_offset] = hash.get();
86 return *this;
87 }
88
89 /* These functions are used for all hash tree addresses (including FORS). */
90
92 m_address[tree_height_offset] = tree_height.get();
93 return *this;
94 }
95
97 m_address[tree_index_offset] = tree_index.get();
98 return *this;
99 }
100
102 m_address[layer_offset] = other.m_address[layer_offset];
103 m_address[tree_offset + 0] = other.m_address[tree_offset + 0];
104 m_address[tree_offset + 1] = other.m_address[tree_offset + 1];
105 m_address[tree_offset + 2] = other.m_address[tree_offset + 2];
106
107 return *this;
108 }
109
111 auto result = Sphincs_Address({0, 0, 0, 0, 0, 0, 0, 0});
112 result.copy_subtree_from(other);
113 return result;
114 }
115
117 m_address[layer_offset] = other.m_address[layer_offset];
118 m_address[tree_offset + 0] = other.m_address[tree_offset + 0];
119 m_address[tree_offset + 1] = other.m_address[tree_offset + 1];
120 m_address[tree_offset + 2] = other.m_address[tree_offset + 2];
121 m_address[keypair_offset] = other.m_address[keypair_offset];
122
123 return *this;
124 }
125
127 Sphincs_Address result({0, 0, 0, 0, 0, 0, 0, 0});
128 result.copy_keypair_from(other);
129 return result;
130 }
131
132 Sphincs_Address_Type get_type() const { return Sphincs_Address_Type(m_address[type_offset]); }
133
134 std::array<uint8_t, 32> to_bytes() const {
135 std::array<uint8_t, sizeof(m_address)> result;
136 for(unsigned int i = 0; i < m_address.size(); ++i) {
137 store_be(m_address[i], result.data() + (i * 4));
138 }
139 return result;
140 }
141
142 std::array<uint8_t, 22> to_bytes_compressed() const {
143 std::array<uint8_t, 22> result;
144
145 result[0] = static_cast<uint8_t>(m_address[layer_offset]);
146 store_be(m_address[tree_offset + 1], &result[1]);
147 store_be(m_address[tree_offset + 2], &result[5]);
148 result[9] = static_cast<uint8_t>(m_address[type_offset]);
149 store_be(m_address[keypair_offset], &result[10]);
150 store_be(m_address[chain_offset], &result[14]);
151 store_be(m_address[hash_offset], &result[18]);
152
153 return result;
154 }
155
156 private:
157 std::array<uint32_t, 8> m_address;
158};
159
160} // namespace Botan
161
162#endif
Sphincs_Address & set_chain(WotsChainIndex chain)
Definition sp_address.h:79
Sphincs_Address_Type get_type() const
Definition sp_address.h:132
Sphincs_Address & copy_subtree_from(const Sphincs_Address &other)
Definition sp_address.h:101
std::array< uint8_t, 22 > to_bytes_compressed() const
Definition sp_address.h:142
Sphincs_Address & set_layer(HypertreeLayerIndex layer)
Definition sp_address.h:55
Sphincs_Address & set_tree_height(TreeLayerIndex tree_height)
Definition sp_address.h:91
Sphincs_Address & set_keypair(TreeNodeIndex keypair)
Definition sp_address.h:74
Sphincs_Address & set_tree_index(TreeNodeIndex tree_index)
Definition sp_address.h:96
static Sphincs_Address as_subtree_from(const Sphincs_Address &other)
Definition sp_address.h:110
Sphincs_Address & set_hash(WotsHashIndex hash)
Definition sp_address.h:84
Sphincs_Address(Sphincs_Address_Type type)
Definition sp_address.h:48
Sphincs_Address & copy_keypair_from(const Sphincs_Address other)
Definition sp_address.h:116
Sphincs_Address & set_tree(XmssTreeIndexInLayer tree)
Definition sp_address.h:60
Sphincs_Address(std::array< uint32_t, 8 > address)
Definition sp_address.h:53
Sphincs_Address & set_type(Sphincs_Address_Type type)
Definition sp_address.h:67
static Sphincs_Address as_keypair_from(const Sphincs_Address &other)
Definition sp_address.h:126
std::array< uint8_t, 32 > to_bytes() const
Definition sp_address.h:134
int(* final)(unsigned char *, CTX *)
#define BOTAN_TEST_API
Definition compiler.h:51
Sphincs_Address_Type
Definition sp_address.h:20
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:711