Botan 3.13.0
Crypto and TLS for C&
xmss.h
Go to the documentation of this file.
1/*
2 * XMSS Keys
3 * (C) 2016,2017 Matthias Gierlings
4 * (C) 2019 René Korthaus, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 **/
8
9#ifndef BOTAN_XMSS_H_
10#define BOTAN_XMSS_H_
11
12#include <botan/pk_keys.h>
13#include <botan/xmss_parameters.h>
14#include <memory>
15#include <span>
16
17namespace Botan {
18
20class XMSS_Address;
21class XMSS_Hash;
22class XMSS_PublicKey_Internal;
23class XMSS_PrivateKey_Internal;
27
28/**
29 * An XMSS: Extended Hash-Based Signature public key.
30 *
31 * [1] XMSS: Extended Hash-Based Signatures,
32 * Request for Comments: 8391
33 * Release: May 2018.
34 * https://datatracker.ietf.org/doc/rfc8391/
35 **/
36class BOTAN_PUBLIC_API(2, 0) XMSS_PublicKey : public virtual Public_Key {
37 public:
38 /**
39 * Creates a new XMSS public key for the chosen XMSS signature method.
40 * New public and prf seeds are generated using rng. The appropriate WOTS
41 * signature method will be automatically set based on the chosen XMSS
42 * signature method.
43 *
44 * @param xmss_oid Identifier for the selected XMSS signature method.
45 * @param rng A random number generator to use for key generation.
46 **/
48
49 /**
50 * Loads a public key from an X.509 SubjectPublicKeyInfo.
51 *
52 * Public key must be encoded as in draft-vangeest-x509-hash-sigs-03.
53 *
54 * @param alg_id the X.509 AlgorithmIdentifier
55 * @param key_bits DER encoded public key bits
56 */
57 XMSS_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits);
58
59 /**
60 * Loads a public key.
61 *
62 * Public key must be encoded as in draft-vangeest-x509-hash-sigs-03.
63 *
64 * @param key_bits DER encoded public key bits
65 */
66 BOTAN_DEPRECATED("Use the constructor taking an AlgorithmIdentifier")
67 BOTAN_FUTURE_EXPLICIT XMSS_PublicKey(std::span<const uint8_t> key_bits);
68
69 /**
70 * Creates a new XMSS public key for a chosen XMSS signature method as
71 * well as pre-computed root node and public_seed values.
72 *
73 * @param xmss_oid Identifier for the selected XMSS signature method.
74 * @param root Root node value.
75 * @param public_seed Public seed value.
76 **/
80
81 std::string algo_name() const override { return "XMSS"; }
82
86
87 bool check_key(RandomNumberGenerator& rng, bool strong) const override;
88
89 size_t estimated_strength() const override;
90
91 size_t key_length() const override;
92
93 /**
94 * Generates a byte sequence representing the XMSS
95 * public key, as defined in [1] (p. 23, "XMSS Public Key")
96 *
97 * @return 4-byte OID, followed by n-byte root node, followed by
98 * public seed.
99 **/
100 std::vector<uint8_t> raw_public_key_bits() const override;
101
102 /**
103 * Returns the encoded public key as defined in RFC
104 * draft-vangeest-x509-hash-sigs-03.
105 *
106 * @return encoded public key bits
107 **/
108 std::vector<uint8_t> public_key_bits() const override;
109
110 BOTAN_DEPRECATED("Use raw_public_key_bits()") std::vector<uint8_t> raw_public_key() const;
111
112 std::unique_ptr<Private_Key> generate_another(RandomNumberGenerator& rng) const final;
113
114 bool supports_operation(PublicKeyOperation op) const override { return (op == PublicKeyOperation::Signature); }
115
116 std::unique_ptr<PK_Ops::Verification> create_verification_op(std::string_view params,
117 std::string_view provider) const override;
118
119 std::unique_ptr<PK_Ops::Verification> create_x509_verification_op(const AlgorithmIdentifier& alg_id,
120 std::string_view provider) const override;
121
122 protected:
124
125 const secure_vector<uint8_t>& public_seed() const;
126
127 const secure_vector<uint8_t>& root() const;
128
129 const XMSS_Parameters& xmss_parameters() const;
130
131 private:
132 std::shared_ptr<const XMSS_PublicKey_Internal> m_public_key;
133};
134
135template <typename>
136class Atomic;
137
138class XMSS_Index_Registry;
139
140/**
141 * Determines how WOTS+ private keys are derived from the XMSS private key
142 */
143enum class WOTS_Derivation_Method : uint8_t {
144 /// This roughly followed the suggestions in RFC 8391 but is vulnerable
145 /// to a multi-target attack. For new private keys, we recommend using
146 /// the derivation as suggested in NIST SP.800-208.
147 /// Private keys generated with Botan 2.x will need to stay with this mode,
148 /// otherwise they won't be able to generate valid signatures any longer.
150
151 /// Derivation as specified in NIST SP.800-208 to avoid a multi-target attack
152 /// on the WOTS+ key derivation suggested in RFC 8391. New private keys
153 /// should use this mode.
155};
156
157/**
158 * An XMSS: Extended Hash-Based Signature private key.
159 * The XMSS private key does not support the X509 and PKCS7 standard. Instead
160 * the raw format described in [1] is used.
161 *
162 * [1] XMSS: Extended Hash-Based Signatures,
163 * Request for Comments: 8391
164 * Release: May 2018.
165 * https://datatracker.ietf.org/doc/rfc8391/
166 **/
167
170
171class BOTAN_PUBLIC_API(2, 0) XMSS_PrivateKey final : public virtual XMSS_PublicKey,
172 public virtual Private_Key {
173 public:
174 /**
175 * Creates a new XMSS private key for the chosen XMSS signature method.
176 * New seeds for public/private key and pseudo random function input are
177 * generated using the provided RNG. The appropriate WOTS signature method
178 * will be automatically set based on the chosen XMSS signature method.
179 *
180 * @param xmss_algo_id Identifier for the selected XMSS signature method.
181 * @param rng A random number generator to use for key generation.
182 * @param wots_derivation_method The method used to derive WOTS+ private keys
183 **/
187
188 /**
189 * Loads a private key from a PKCS #8 PrivateKeyInfo.
190 *
191 * @param alg_id the PKCS #8 AlgorithmIdentifier
192 * @param key_bits An XMSS private key serialized using raw_private_key().
193 **/
194 XMSS_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits);
195
196 /**
197 * Creates an XMSS_PrivateKey from a byte sequence produced by
198 * raw_private_key().
199 *
200 * @param raw_key An XMSS private key serialized using raw_private_key().
201 **/
202 BOTAN_DEPRECATED("Use the constructor taking an AlgorithmIdentifier")
203 BOTAN_FUTURE_EXPLICIT XMSS_PrivateKey(std::span<const uint8_t> raw_key);
204
205 /**
206 * Creates a new XMSS private key for the chosen XMSS signature method
207 * using precomputed seeds for public/private keys and pseudo random
208 * function input. The appropriate WOTS signature method will be
209 * automatically set, based on the chosen XMSS signature method.
210 *
211 * @param xmss_algo_id Identifier for the selected XMSS signature method.
212 * @param idx_leaf Index of the next unused leaf.
213 * @param wots_priv_seed A seed to generate a Winternitz-One-Time-
214 * Signature private key from.
215 * @param prf a secret n-byte key sourced from a secure source
216 * of uniformly random data.
217 * @param root Root node of the binary hash tree.
218 * @param public_seed The public seed.
219 * @param wots_derivation_method The method used to derive WOTS+ private keys
220 **/
222 size_t idx_leaf,
223 secure_vector<uint8_t> wots_priv_seed,
228
229 bool stateful_operation() const override { return true; }
230
231 std::unique_ptr<Public_Key> public_key() const override;
232
233 /**
234 * Retrieves the last unused leaf index of the private key. Reusing a leaf
235 * by utilizing leaf indices lower than the last unused leaf index will
236 * compromise security.
237 *
238 * @return Index of the last unused leaf.
239 **/
240 BOTAN_DEPRECATED("Use remaining_operations()") size_t unused_leaf_index() const;
241
242 /**
243 * Retrieves the number of remaining signatures for this private key.
244 */
245 BOTAN_DEPRECATED("Use remaining_operations()") size_t remaining_signatures() const;
246
247 std::optional<uint64_t> remaining_operations() const override;
248
249 std::unique_ptr<PK_Ops::Signature> create_signature_op(RandomNumberGenerator& rng,
250 std::string_view params,
251 std::string_view provider) const override;
252
253 secure_vector<uint8_t> private_key_bits() const override;
254
255 /**
256 * Generates a non standardized byte sequence representing the XMSS
257 * private key.
258 *
259 * @return byte sequence consisting of the following elements in order:
260 * 4-byte OID, n-byte root node, n-byte public seed,
261 * 4-byte unused leaf index, n-byte prf seed, n-byte private seed.
262 * At last 1-byte that encodes the WOTS+ key derivation method.
263 **/
264 secure_vector<uint8_t> raw_private_key() const;
265
266 WOTS_Derivation_Method wots_derivation_method() const;
267
268 private:
270
271 // The seeds and the precomputed Merkle root produced during key
272 // generation, used to construct the (immutable) public key before the
273 // derived private key body runs.
274 struct Keygen_Material;
275
276 XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
278 Keygen_Material material);
279
280 static Keygen_Material generate_keygen_material(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
283
284 size_t reserve_unused_leaf_index();
285
286 const secure_vector<uint8_t>& prf_value() const;
287
288 XMSS_WOTS_PrivateKey wots_private_key_for(const XMSS_Address& adrs, XMSS_Hash& hash) const;
289
290 /**
291 * Algorithm 9: "treeHash"
292 * Computes the internal n-byte nodes of a Merkle tree.
293 *
294 * @param start_idx The start index.
295 * @param target_node_height Height of the target node.
296 * @param adrs Address of the tree containing the target node.
297 * @param hash The hash function to use
298 *
299 * @return The root node of a tree of height target_node height with the
300 * leftmost leaf being the hash of the WOTS+ pk with index
301 * start_idx.
302 **/
303 secure_vector<uint8_t> tree_hash(size_t start_idx,
304 size_t target_node_height,
305 const XMSS_Address& adrs,
306 XMSS_Hash& hash) const;
307
308 std::shared_ptr<const XMSS_PrivateKey_Internal> m_private;
309};
310
312
313} // namespace Botan
314
315#endif
#define BOTAN_DIAGNOSTIC_POP
Definition api.h:128
#define BOTAN_DIAGNOSTIC_PUSH
Definition api.h:125
#define BOTAN_DIAGNOSTIC_IGNORE_INHERITED_VIA_DOMINANCE
Definition api.h:127
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
virtual OID object_identifier() const
Definition pk_keys.cpp:22
bool stateful_operation() const override
Definition xmss.h:229
friend class XMSS_Signature_Operation
Definition xmss.h:269
WOTS_Derivation_Method wots_derivation_method() const
XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id, RandomNumberGenerator &rng, WOTS_Derivation_Method wots_derivation_method=WOTS_Derivation_Method::NIST_SP800_208)
const secure_vector< uint8_t > & root() const
const secure_vector< uint8_t > & public_seed() const
const XMSS_Parameters & xmss_parameters() const
bool supports_operation(PublicKeyOperation op) const override
Definition xmss.h:114
friend class XMSS_Verification_Operation
Definition xmss.h:123
std::string algo_name() const override
Definition xmss.h:81
AlgorithmIdentifier algorithm_identifier() const override
Definition xmss.h:83
XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid, RandomNumberGenerator &rng)
PublicKeyOperation
Definition pk_keys.h:46
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
WOTS_Derivation_Method
Definition xmss.h:143