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

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

#include <hss.h>

Public Member Functions

void _const_time_poison () const
 
void _const_time_unpoison () const
 
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.
 
std::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 126 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 121 of file hss.cpp.

121 :
122 m_hss_params(hss_params), m_current_idx(0), m_sig_size(HSS_Signature::size(m_hss_params)) {
123 m_hss_seed = rng.random_vec<LMS_Seed>(m_hss_params.params_at_level(HSS_Level(0)).lms_params().m());
124 m_identifier = rng.random_vec<LMS_Identifier>(LMS_IDENTIFIER_LEN);
125}
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:98
const HSS_LMS_Params & hss_params() const
Returns the used HSS-LMS parameters.
Definition hss.h:148
static size_t size(const HSS_LMS_Params &params)
Returns the size a signature would have in its encoded format.
Definition hss.cpp:406
constexpr size_t LMS_IDENTIFIER_LEN
The length in bytes of the LMS identifier (I).
Definition lms.h:67
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:34

References Botan::LMS_IDENTIFIER_LEN, Botan::HSS_LMS_Params::params_at_level(), and Botan::RandomNumberGenerator::random_vec().

Referenced by from_bytes_or_throw().

Member Function Documentation

◆ _const_time_poison()

void Botan::HSS_LMS_PrivateKeyInternal::_const_time_poison ( ) const
inline

Definition at line 197 of file hss.h.

197{ CT::poison(m_hss_seed); }
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:53

References Botan::CT::poison().

◆ _const_time_unpoison()

void Botan::HSS_LMS_PrivateKeyInternal::_const_time_unpoison ( ) const
inline

Definition at line 199 of file hss.h.

199{ CT::unpoison(m_hss_seed); }
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:64

References Botan::CT::unpoison().

◆ 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 127 of file hss.cpp.

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

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 158 of file hss.h.

158{ 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 275 of file hss.cpp.

275 {
276 auto& top_params = hss_params().params_at_level(HSS_Level(0));
277 return LMS_PrivateKey(top_params.lms_params(), top_params.lmots_params(), m_identifier, m_hss_seed);
278}

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 148 of file hss.h.

148{ 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 194 of file hss.cpp.

194 {
195 m_current_idx = idx;
196}

◆ sign()

std::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 228 of file hss.cpp.

228 {
229 std::vector<uint8_t> sig(HSS_Signature::size(hss_params()));
230 BufferStuffer sig_stuffer(sig);
231 sig_stuffer.append(store_be(hss_params().L() - 1));
232
233 std::vector<LMS_Tree_Node_Idx> q = derive_lms_leaf_indices_from_hss_index(reserve_next_idx(), hss_params());
234
235 // Derive LMS private keys and compute buffers
236 std::vector<LMS_PrivateKey> lms_key_at_layer;
237 std::vector<StrongSpan<LMS_Signature_Bytes>> out_lms_sig_buffer_at_layer;
238 std::vector<std::span<uint8_t>> out_child_pk_buffer_at_layer;
239 for(HSS_Level layer(0); layer < hss_params().L(); ++layer) {
240 // Generate key for current layer
241 const HSS_LMS_Params::LMS_LMOTS_Params_Pair& layer_params = hss_params().params_at_level(layer);
242 if(layer == HSS_Level(0)) {
243 lms_key_at_layer.push_back(hss_derive_root_lms_private_key());
244 } else {
245 lms_key_at_layer.push_back(
246 hss_derive_child_lms_private_key(layer_params, lms_key_at_layer.back(), q.at(layer.get() - 1)));
247 out_child_pk_buffer_at_layer.push_back(sig_stuffer.next(LMS_PublicKey::size(layer_params.lms_params())));
248 }
249 out_lms_sig_buffer_at_layer.push_back(sig_stuffer.next<LMS_Signature_Bytes>(
250 LMS_Signature::size(layer_params.lms_params(), layer_params.lmots_params())));
251 }
252 BOTAN_ASSERT_NOMSG(sig_stuffer.full());
253
254 // Sign and write the signature from bottom layer to root layer
255 std::vector<uint8_t> current_pk;
256 for(int32_t layer_it = hss_params().L().get() - 1; layer_it >= 0; --layer_it) {
257 HSS_Level layer(layer_it);
258 if(layer == hss_params().L() - 1) {
259 current_pk =
260 lms_key_at_layer.at(layer.get())
261 .sign_and_get_pk(out_lms_sig_buffer_at_layer.at(layer.get()), q.at(layer.get()), LMS_Message(msg))
262 .to_bytes();
263 } else {
264 copy_mem(out_child_pk_buffer_at_layer.at(layer.get()), current_pk);
265 current_pk =
266 lms_key_at_layer.at(layer.get())
267 .sign_and_get_pk(out_lms_sig_buffer_at_layer.at(layer.get()), q.at(layer.get()), LMS_Message(current_pk))
268 .to_bytes();
269 }
270 }
271
272 return sig;
273}
#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:103
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:275
static size_t size(const LMS_Params &lms_params)
The expected size of an LMS public key for given lms_params.
Definition lms.cpp:313
static size_t size(const LMS_Params &lms_params, const LMOTS_Params &lmots_params)
Definition lms.cpp:419
Strong< std::vector< uint8_t >, struct LMS_Signature_Bytes_ > LMS_Signature_Bytes
Raw bytes of an LMS signature.
Definition lms.h:82
Strong< std::vector< uint8_t >, struct LMS_Message_ > LMS_Message
A message that is signed with an LMS tree.
Definition lm_ots.h:55
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:147
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:773

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 195 of file hss.h.

195{ 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 175 of file hss.cpp.

175 {
176 secure_vector<uint8_t> sk_bytes(size());
177 BufferStuffer stuffer(sk_bytes);
178
179 stuffer.append(store_be(hss_params().L()));
180 stuffer.append(store_be(get_idx()));
181
182 for(HSS_Level layer(1); layer <= hss_params().L(); ++layer) {
183 const auto& params = hss_params().params_at_level(layer - 1);
184 stuffer.append(store_be(params.lms_params().algorithm_type()));
185 stuffer.append(store_be(params.lmots_params().algorithm_type()));
186 }
187 stuffer.append(m_hss_seed);
188 stuffer.append(m_identifier);
189 BOTAN_ASSERT_NOMSG(stuffer.full());
190
191 return sk_bytes;
192}
HSS_Sig_Idx get_idx() const
Get the idx of the next signature to generate.
Definition hss.h:158
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61

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: