Botan 3.13.0
Crypto and TLS for C&
hss_lms.h
Go to the documentation of this file.
1/*
2 * Hierarchical Signature System (HSS) / Leighton-Micali Signature (LMS)
3 * hash-based signature algorithm (RFC 8554).
4 *
5 * (C) 2023 Jack Lloyd
6 * 2023 Philippe Lieser, Fabian Albert - Rohde & Schwarz Cybersecurity GmbH
7 *
8 * Botan is released under the Simplified BSD License (see license.txt)
9 **/
10
11#ifndef BOTAN_HSS_LMS_H_
12#define BOTAN_HSS_LMS_H_
13
14#include <botan/pk_keys.h>
15
16#include <memory>
17#include <vector>
18
19namespace Botan {
20
23
24/**
25 * @brief An HSS/LMS public key.
26 *
27 * Implementation of the Hierarchical Signature System (HSS) of
28 * Leighton-Micali Hash-Based Signatures (LMS) defined in RFC 8554
29 * (https://www.rfc-editor.org/rfc/rfc8554.html).
30 *
31 * To derive seeds for single LMS trees in the HSS-multitree, the method (SECRET_METHOD 2)
32 * of the reference implementation (https://github.com/cisco/hash-sigs) is used.
33 */
34class BOTAN_PUBLIC_API(3, 5) HSS_LMS_PublicKey : public virtual Public_Key {
35 public:
36 /**
37 * @brief Load a public key from an X.509 SubjectPublicKeyInfo.
38 */
39 HSS_LMS_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits);
40
41 /**
42 * @brief Load an existing public key using its bytes.
43 */
44 BOTAN_DEPRECATED("Use the constructor taking an AlgorithmIdentifier")
45 BOTAN_FUTURE_EXPLICIT HSS_LMS_PublicKey(std::span<const uint8_t> pub_key_bytes);
46
48 HSS_LMS_PublicKey(const HSS_LMS_PublicKey& other) = default;
52
53 size_t key_length() const override;
54
55 std::string algo_name() const override;
56
57 size_t estimated_strength() const override;
59 OID object_identifier() const override;
60 bool check_key(RandomNumberGenerator& rng, bool strong) const override;
61 std::vector<uint8_t> raw_public_key_bits() const override;
62 std::vector<uint8_t> public_key_bits() const override;
63
64 std::unique_ptr<PK_Ops::Verification> create_verification_op(std::string_view params,
65 std::string_view provider) const override;
66
67 std::unique_ptr<PK_Ops::Verification> create_x509_verification_op(const AlgorithmIdentifier& signature_algorithm,
68 std::string_view provider) const override;
69
70 bool supports_operation(PublicKeyOperation op) const override;
71
72 /**
73 * @throws Not_Implemented for LMS public keys.
74 */
75 std::unique_ptr<Private_Key> generate_another(RandomNumberGenerator& rng) const override;
76
77 protected:
78 HSS_LMS_PublicKey() = default;
79
80 std::shared_ptr<const HSS_LMS_PublicKeyInternal> m_public; // NOLINT(*non-private-member-variable*)
81};
82
85
86/**
87 * @brief An HSS/LMS private key.
88 *
89 * HSS/LMS is a statefule hash-based signature scheme. This means the private key must
90 * be (securely) updated after using it for signing. Also, there is a maximal number
91 * of signatures that can be created using one HSS/LMS key pair, which depends on
92 * the number and size of LMS layers of the chosen HSS/LMS instance. For the selection
93 * of a sensible parameter set, refer to RFC 8554 6.4.
94 *
95 * The format of the HSS/LMS private key is not defined in
96 * RFC 8554. We use the following format (big endian):
97 *
98 * PrivateKey = u32str(L) || u64str(idx) ||
99 * u32str(LMS algorithm id (root layer)) || u32str(LMOTS algorithm id (root layer)) ||
100 * ... ||
101 * u32str(LMS algorithm id (bottom layer)) || u32str(LMOTS algorithm id (bottom layer)) ||
102 * HSS_SEED || HSS_Identifier
103 *
104 * L: Number of LMS layers
105 * Idx: Number of signatures already created using this private key
106 * HSS_SEED: Seed to derive LMS Seeds (see RFC 8554 Appendix A) like in SECRET_METHOD 2 of
107 * https://github.com/cisco/hash-sigs. As long as the hash functions output length.
108 * HSS_Identifier: 16 bytes long.
109 *
110 * The HSS/LMS instance to use for creating new keys is defined using an algorithm parameter sting,
111 * i.e. to define which hash function (hash), LMS tree height (h)
112 * and OTS Winternitz coefficient widths (w) to use. The syntax is the following:
113 *
114 * HSS-LMS(<hash>,HW(<h>,<w>),HW(<h>,<w>),...)
115 *
116 * e.g. 'HSS-LMS(SHA-256,HW(5,1),HW(5,1))' to use SHA-256 in a two-layer HSS instance
117 * with a LMS tree height 5 and w=1. The following parameters are allowed (which are
118 * specified in RFC 8554 and draft-fluhrer-lms-more-parm-sets-11):
119 *
120 * hash: 'SHA-256', 'Truncated(SHA-256,192)', 'SHAKE-256(256)', SHAKE-256(192)
121 * h: '5', '10', '15', '20', '25'
122 * w: '1', '2', '4', '8'
123 *
124 * Note: The selected hash function is also used for seed derivation.
125 */
126class BOTAN_PUBLIC_API(3, 5) HSS_LMS_PrivateKey final : public virtual HSS_LMS_PublicKey,
127 public virtual Private_Key {
128 public:
129 /**
130 * @brief Load a private key from a PKCS #8 PrivateKeyInfo.
131 */
132 HSS_LMS_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits);
133
134 /**
135 * @brief Load an existing LMS private key using its bytes
136 */
137 BOTAN_DEPRECATED("Use the constructor taking an AlgorithmIdentifier")
138 BOTAN_FUTURE_EXPLICIT HSS_LMS_PrivateKey(std::span<const uint8_t> private_key_bytes);
139
140 /**
141 * @brief Construct a new hss lms privatekey object.
142 *
143 * @param rng random number generator
144 * @param algo_params string is format 'HSS-LMS(<hash>,HW(<h>,<w>),HW(<h>,<w>),...)'
145 */
146 HSS_LMS_PrivateKey(RandomNumberGenerator& rng, std::string_view algo_params);
147
153
156 std::unique_ptr<Public_Key> public_key() const override;
157
159
160 bool stateful_operation() const override { return true; }
161
162 /**
163 * Retrieves the number of remaining signatures for this private key.
164 */
165 std::optional<uint64_t> remaining_operations() const override;
166
167 std::unique_ptr<Private_Key> generate_another(RandomNumberGenerator& rng) const override;
168
169 std::unique_ptr<PK_Ops::Signature> create_signature_op(RandomNumberGenerator& rng,
170 std::string_view params,
171 std::string_view provider) const override;
172
173 private:
174 explicit HSS_LMS_PrivateKey(std::shared_ptr<HSS_LMS_PrivateKeyInternal> sk);
175
176 std::shared_ptr<const HSS_LMS_PrivateKeyInternal> m_private;
177};
178
180
181} // namespace Botan
182
183#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
The internal HSS-LMS private key.
Definition hss.h:127
An HSS/LMS private key.
Definition hss_lms.h:127
std::unique_ptr< Public_Key > public_key() const override
Definition hss_lms.cpp:173
AlgorithmIdentifier pkcs8_algorithm_identifier() const override
Definition hss_lms.cpp:180
HSS_LMS_PrivateKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
Load a private key from a PKCS #8 PrivateKeyInfo.
Definition hss_lms.cpp:135
bool stateful_operation() const override
Definition hss_lms.h:160
HSS_LMS_PrivateKey(const HSS_LMS_PrivateKey &other)=delete
secure_vector< uint8_t > raw_private_key_bits() const override
Definition hss_lms.cpp:169
HSS_LMS_PrivateKey & operator=(HSS_LMS_PrivateKey &&other)=delete
secure_vector< uint8_t > private_key_bits() const override
Definition hss_lms.cpp:164
HSS_LMS_PrivateKey & operator=(const HSS_LMS_PrivateKey &other)=delete
HSS_LMS_PrivateKey(HSS_LMS_PrivateKey &&other)=default
The internal HSS-LMS public key.
Definition hss.h:252
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
Definition hss_lms.cpp:103
HSS_LMS_PublicKey & operator=(HSS_LMS_PublicKey &&other)=delete
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const override
Definition hss_lms.cpp:126
size_t key_length() const override
Definition hss_lms.cpp:33
bool supports_operation(PublicKeyOperation op) const override
Definition hss_lms.cpp:122
HSS_LMS_PublicKey(const HSS_LMS_PublicKey &other)=default
std::vector< uint8_t > raw_public_key_bits() const override
Definition hss_lms.cpp:62
HSS_LMS_PublicKey(HSS_LMS_PublicKey &&other)=default
std::string algo_name() const override
Definition hss_lms.cpp:45
HSS_LMS_PublicKey & operator=(const HSS_LMS_PublicKey &other)=delete
OID object_identifier() const override
Definition hss_lms.cpp:53
std::shared_ptr< const HSS_LMS_PublicKeyInternal > m_public
Definition hss_lms.h:80
size_t estimated_strength() const override
Definition hss_lms.cpp:37
std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const override
Definition hss_lms.cpp:111
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition hss_lms.cpp:57
HSS_LMS_PublicKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
Load a public key from an X.509 SubjectPublicKeyInfo.
Definition hss_lms.cpp:20
std::vector< uint8_t > public_key_bits() const override
Definition hss_lms.cpp:66
AlgorithmIdentifier algorithm_identifier() const override
Definition hss_lms.cpp:49
PublicKeyOperation
Definition pk_keys.h:46
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128