Botan 3.5.0
Crypto and TLS for C&
Botan::HSS_LMS_PrivateKeyInternal Class Referencefinal

The internal HSS-LMS private key. More...

#include <hss.h>

Public Member Functions

HSS_Sig_Idx get_idx () const
 Get the idx of the next signature to generate.
 
LMS_PrivateKey hss_derive_root_lms_private_key () const
 Create the HSS root LMS tree's LMS_PrivateKey using the HSS-LMS private key.
 
 HSS_LMS_PrivateKeyInternal (const HSS_LMS_Params &hss_params, RandomNumberGenerator &rng)
 Create an internal HSS-LMS private key.
 
const HSS_LMS_Paramshss_params () const
 Returns the used HSS-LMS parameters.
 
void set_idx (HSS_Sig_Idx idx)
 Set the idx of the next signature to generate.
 
secure_vector< uint8_t > sign (std::span< const uint8_t > msg)
 Create a HSS-LMS signature.
 
size_t signature_size () const
 Returns the size in bytes of a signature created by this key.
 
secure_vector< uint8_t > to_bytes () const
 Returns the key in its encoded format.
 

Static Public Member Functions

static std::shared_ptr< HSS_LMS_PrivateKeyInternalfrom_bytes_or_throw (std::span< const uint8_t > key_bytes)
 Parse a private HSS-LMS key.
 

Detailed Description

The internal HSS-LMS private key.

Note that the format is not specified in the RFC 8554, and is Botan specific.

Definition at line 125 of file hss.h.

Constructor & Destructor Documentation

◆ HSS_LMS_PrivateKeyInternal()

Botan::HSS_LMS_PrivateKeyInternal::HSS_LMS_PrivateKeyInternal ( const HSS_LMS_Params & hss_params,
RandomNumberGenerator & rng )

Create an internal HSS-LMS private key.

Parameters
hss_paramsThe HSS-LMS parameters for the key.
rngThe rng to use.

Definition at line 114 of file hss.cpp.

114 :
115 m_hss_params(hss_params), m_current_idx(0), m_sig_size(HSS_Signature::size(m_hss_params)) {
116 m_hss_seed = rng.random_vec<LMS_Seed>(m_hss_params.params_at_level(HSS_Level(0)).lms_params().m());
117 m_identifier = rng.random_vec<LMS_Identifier>(LMS_IDENTIFIER_LEN);
118}
const LMS_Params & lms_params() const
The LMS parameters.
Definition hss.h:50
const LMS_LMOTS_Params_Pair & params_at_level(HSS_Level level) const
Returns the LMS an LM-OTS parameters at the specified level of the HSS tree.
Definition hss.h:97
const HSS_LMS_Params & hss_params() const
Returns the used HSS-LMS parameters.
Definition hss.h:147
static size_t size(const HSS_LMS_Params &params)
Returns the size a signature would have in its encoded format.
Definition hss.cpp:398
size_t m() const
Returns the number of bytes associated with each node.
Definition lms.h:118
constexpr size_t LMS_IDENTIFIER_LEN
The length in bytes of the LMS identifier (I).
Definition lms.h:66
Strong< std::vector< uint8_t >, struct LMS_Identifier_ > LMS_Identifier
The identifier of an LMS tree (I in RFC 8554)
Definition lm_ots.h:50
Strong< secure_vector< uint8_t >, struct LMS_SEED_ > LMS_Seed
Seed of the LMS tree, used to generate the LM-OTS private keys.
Definition lm_ots.h:25
Strong< uint32_t, struct HSS_Level_, EnableArithmeticWithPlainNumber > HSS_Level
The HSS layer in the HSS multi tree starting at 0 from the root.
Definition hss.h:33

References Botan::LMS_IDENTIFIER_LEN, Botan::HSS_LMS_Params::LMS_LMOTS_Params_Pair::lms_params(), Botan::LMS_Params::m(), Botan::HSS_LMS_Params::params_at_level(), and Botan::RandomNumberGenerator::random_vec().

Referenced by from_bytes_or_throw().

Member Function Documentation

◆ from_bytes_or_throw()

std::shared_ptr< HSS_LMS_PrivateKeyInternal > Botan::HSS_LMS_PrivateKeyInternal::from_bytes_or_throw ( std::span< const uint8_t > key_bytes)
static

Parse a private HSS-LMS key.

Parameters
key_bytesThe private key bytes to parse.
Returns
The internal HSS-LMS private key.
Exceptions
Decoding_ErrorIf parsing the private key fails.

Definition at line 120 of file hss.cpp.

121 {
122 if(key_bytes.size() < sizeof(HSS_Level) + sizeof(HSS_Sig_Idx)) {
123 throw Decoding_Error("Too few private key bytes.");
124 }
125 BufferSlicer slicer(key_bytes);
126
127 const auto L = load_be<HSS_Level>(slicer.take<sizeof(HSS_Level)>());
128 if(L == 0U || L > HSS_MAX_LEVELS) {
129 throw Decoding_Error("Invalid number of HSS layers in private HSS-LMS key.");
130 }
131
132 const auto sig_idx = load_be<HSS_Sig_Idx>(slicer.take<sizeof(HSS_Sig_Idx)>());
133
134 std::vector<HSS_LMS_Params::LMS_LMOTS_Params_Pair> params;
135 for(size_t layer = 1; layer <= L; ++layer) {
136 if(slicer.remaining() < sizeof(LMS_Algorithm_Type) + sizeof(LMOTS_Algorithm_Type)) {
137 throw Decoding_Error("Out of bytes while parsing private HSS-LMS key.");
138 }
139 const auto lms_type = load_be<LMS_Algorithm_Type>(slicer.take<sizeof(LMS_Algorithm_Type)>());
140 const auto lmots_type = load_be<LMOTS_Algorithm_Type>(slicer.take<sizeof(LMOTS_Algorithm_Type)>());
141 params.push_back({LMS_Params::create_or_throw(lms_type), LMOTS_Params::create_or_throw(lmots_type)});
142 }
143 std::string hash_name = params.at(0).lms_params().hash_name();
144 if(std::any_of(params.begin(), params.end(), [&hash_name](HSS_LMS_Params::LMS_LMOTS_Params_Pair& lms_lmots_params) {
145 bool invalid_lmots_hash = lms_lmots_params.lmots_params().hash_name() != hash_name;
146 bool invalid_lms_hash = lms_lmots_params.lms_params().hash_name() != hash_name;
147 return invalid_lmots_hash || invalid_lms_hash;
148 })) {
149 throw Decoding_Error("Inconsistent hash functions are not allowed.");
150 }
151
152 if(slicer.remaining() < params.at(0).lms_params().m() + LMS_IDENTIFIER_LEN) {
153 throw Decoding_Error("Out of bytes while parsing private HSS-LMS key.");
154 }
155 auto hss_seed = slicer.copy<LMS_Seed>(params.at(0).lms_params().m());
156 auto identifier = slicer.copy<LMS_Identifier>(LMS_IDENTIFIER_LEN);
157
158 if(!slicer.empty()) {
159 throw Decoding_Error("Private HSS-LMS key contains more bytes than expected.");
160 }
161 auto sk = std::shared_ptr<HSS_LMS_PrivateKeyInternal>(
162 new HSS_LMS_PrivateKeyInternal(HSS_LMS_Params(std::move(params)), std::move(hss_seed), std::move(identifier)));
163
164 sk->set_idx(sig_idx);
165 return sk;
166}
HSS_LMS_PrivateKeyInternal(const HSS_LMS_Params &hss_params, RandomNumberGenerator &rng)
Create an internal HSS-LMS private key.
Definition hss.cpp:114
static LMOTS_Params create_or_throw(LMOTS_Algorithm_Type type)
Create the LM-OTS parameters from a known algorithm type.
Definition lm_ots.cpp:99
static LMS_Params create_or_throw(LMS_Algorithm_Type type)
Create the LMS parameters from a known algorithm type.
Definition lms.cpp:112
LMS_Algorithm_Type
Enum of available LMS algorithm types.
Definition lms.h:29
Strong< uint64_t, struct HSS_Sig_Idx_, EnableArithmeticWithPlainNumber > HSS_Sig_Idx
The index of a node within a specific LMS tree layer.
Definition hss.h:28
LMOTS_Algorithm_Type
Enum of available LM-OTS algorithm types.
Definition lm_ots.h:65
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:467

References Botan::BufferSlicer::copy(), Botan::LMOTS_Params::create_or_throw(), Botan::LMS_Params::create_or_throw(), Botan::BufferSlicer::empty(), HSS_LMS_PrivateKeyInternal(), Botan::LMS_IDENTIFIER_LEN, Botan::load_be(), Botan::BufferSlicer::remaining(), and Botan::BufferSlicer::take().

Referenced by Botan::HSS_LMS_PrivateKey::HSS_LMS_PrivateKey().

◆ get_idx()

HSS_Sig_Idx Botan::HSS_LMS_PrivateKeyInternal::get_idx ( ) const
inline

Get the idx of the next signature to generate.

Definition at line 157 of file hss.h.

157{ return m_current_idx; }

Referenced by to_bytes().

◆ hss_derive_root_lms_private_key()

LMS_PrivateKey Botan::HSS_LMS_PrivateKeyInternal::hss_derive_root_lms_private_key ( ) const

Create the HSS root LMS tree's LMS_PrivateKey using the HSS-LMS private key.

We use the same generation as the reference implementation (https://github.com/cisco/hash-sigs) with SECRET_METHOD==2.

Returns
The LMS private key

Definition at line 268 of file hss.cpp.

268 {
269 auto& top_params = hss_params().params_at_level(HSS_Level(0));
270 return LMS_PrivateKey(top_params.lms_params(), top_params.lmots_params(), m_identifier, m_hss_seed);
271}

References hss_params(), and Botan::HSS_LMS_Params::params_at_level().

Referenced by Botan::HSS_LMS_PublicKeyInternal::create(), and sign().

◆ hss_params()

const HSS_LMS_Params & Botan::HSS_LMS_PrivateKeyInternal::hss_params ( ) const
inline

Returns the used HSS-LMS parameters.

Definition at line 147 of file hss.h.

147{ return m_hss_params; }

Referenced by Botan::HSS_LMS_PublicKeyInternal::create(), hss_derive_root_lms_private_key(), sign(), and to_bytes().

◆ set_idx()

void Botan::HSS_LMS_PrivateKeyInternal::set_idx ( HSS_Sig_Idx idx)

Set the idx of the next signature to generate.

Note that creating two signatures with the same index is insecure. The index must be lower than hss_params().max_sig_count().

Definition at line 187 of file hss.cpp.

187 {
188 m_current_idx = idx;
189}

◆ sign()

secure_vector< uint8_t > Botan::HSS_LMS_PrivateKeyInternal::sign ( std::span< const uint8_t > msg)

Create a HSS-LMS signature.

See RFC 8554 6.2 - Algorithm 8.

For each signature creation the hypertree is computed once again, so no data is stored between multiple signatures. However, storing data between multiple signatures could be an optimization if applications create multiple signatures in one go.

Parameters
msgThe message to sign.

Definition at line 221 of file hss.cpp.

221 {
223 BufferStuffer sig_stuffer(sig);
224 sig_stuffer.append(store_be(hss_params().L() - 1));
225
226 std::vector<LMS_Tree_Node_Idx> q = derive_lms_leaf_indices_from_hss_index(reserve_next_idx(), hss_params());
227
228 // Derive LMS private keys and compute buffers
229 std::vector<LMS_PrivateKey> lms_key_at_layer;
230 std::vector<StrongSpan<LMS_Signature_Bytes>> out_lms_sig_buffer_at_layer;
231 std::vector<std::span<uint8_t>> out_child_pk_buffer_at_layer;
232 for(HSS_Level layer(0); layer < hss_params().L(); ++layer) {
233 // Generate key for current layer
234 const HSS_LMS_Params::LMS_LMOTS_Params_Pair& layer_params = hss_params().params_at_level(layer);
235 if(layer == HSS_Level(0)) {
236 lms_key_at_layer.push_back(hss_derive_root_lms_private_key());
237 } else {
238 lms_key_at_layer.push_back(
239 hss_derive_child_lms_private_key(layer_params, lms_key_at_layer.back(), q.at(layer.get() - 1)));
240 out_child_pk_buffer_at_layer.push_back(sig_stuffer.next(LMS_PublicKey::size(layer_params.lms_params())));
241 }
242 out_lms_sig_buffer_at_layer.push_back(sig_stuffer.next<LMS_Signature_Bytes>(
243 LMS_Signature::size(layer_params.lms_params(), layer_params.lmots_params())));
244 }
245 BOTAN_ASSERT_NOMSG(sig_stuffer.full());
246
247 // Sign and write the signature from bottom layer to root layer
248 std::vector<uint8_t> current_pk;
249 for(int32_t layer_it = hss_params().L().get() - 1; layer_it >= 0; --layer_it) {
250 HSS_Level layer(layer_it);
251 if(layer == hss_params().L() - 1) {
252 current_pk =
253 lms_key_at_layer.at(layer.get())
254 .sign_and_get_pk(out_lms_sig_buffer_at_layer.at(layer.get()), q.at(layer.get()), LMS_Message(msg))
255 .to_bytes();
256 } else {
257 copy_mem(out_child_pk_buffer_at_layer.at(layer.get()), current_pk);
258 current_pk =
259 lms_key_at_layer.at(layer.get())
260 .sign_and_get_pk(out_lms_sig_buffer_at_layer.at(layer.get()), q.at(layer.get()), LMS_Message(current_pk))
261 .to_bytes();
262 }
263 }
264
265 return sig;
266}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
HSS_Level L() const
Returns the number of layers the HSS tree has.
Definition hss.h:102
LMS_PrivateKey hss_derive_root_lms_private_key() const
Create the HSS root LMS tree's LMS_PrivateKey using the HSS-LMS private key.
Definition hss.cpp:268
static size_t size(const LMS_Params &lms_params)
The expected size of an LMS public key for given lms_params.
Definition lms.cpp:312
static size_t size(const LMS_Params &lms_params, const LMOTS_Params &lmots_params)
Definition lms.cpp:418
Strong< std::vector< uint8_t >, struct LMS_Signature_Bytes_ > LMS_Signature_Bytes
Raw bytes of an LMS signature.
Definition lms.h:81
Strong< std::vector< uint8_t >, struct LMS_Message_ > LMS_Message
A message that is signed with an LMS tree.
Definition lm_ots.h:55
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:707

References Botan::BufferStuffer::append(), BOTAN_ASSERT_NOMSG, Botan::copy_mem(), Botan::BufferStuffer::full(), Botan::detail::Strong_Base< T >::get(), hss_derive_root_lms_private_key(), hss_params(), Botan::HSS_LMS_Params::L(), Botan::HSS_LMS_Params::LMS_LMOTS_Params_Pair::lmots_params(), Botan::HSS_LMS_Params::LMS_LMOTS_Params_Pair::lms_params(), Botan::BufferStuffer::next(), Botan::HSS_LMS_Params::params_at_level(), Botan::HSS_Signature::size(), Botan::LMS_PublicKey::size(), Botan::LMS_Signature::size(), and Botan::store_be().

◆ signature_size()

size_t Botan::HSS_LMS_PrivateKeyInternal::signature_size ( ) const
inline

Returns the size in bytes of a signature created by this key.

Definition at line 194 of file hss.h.

194{ return m_sig_size; }

◆ to_bytes()

secure_vector< uint8_t > Botan::HSS_LMS_PrivateKeyInternal::to_bytes ( ) const

Returns the key in its encoded format.

Definition at line 168 of file hss.cpp.

168 {
169 secure_vector<uint8_t> sk_bytes(size());
170 BufferStuffer stuffer(sk_bytes);
171
172 stuffer.append(store_be(hss_params().L()));
173 stuffer.append(store_be(get_idx()));
174
175 for(HSS_Level layer(1); layer <= hss_params().L(); ++layer) {
176 const auto& params = hss_params().params_at_level(layer - 1);
177 stuffer.append(store_be(params.lms_params().algorithm_type()));
178 stuffer.append(store_be(params.lmots_params().algorithm_type()));
179 }
180 stuffer.append(m_hss_seed);
181 stuffer.append(m_identifier);
182 BOTAN_ASSERT_NOMSG(stuffer.full());
183
184 return sk_bytes;
185}
HSS_Sig_Idx get_idx() const
Get the idx of the next signature to generate.
Definition hss.h:157

References Botan::BufferStuffer::append(), BOTAN_ASSERT_NOMSG, Botan::BufferStuffer::full(), get_idx(), hss_params(), Botan::HSS_LMS_Params::L(), Botan::HSS_LMS_Params::params_at_level(), and Botan::store_be().


The documentation for this class was generated from the following files: