Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions src/lib/pubkey/xmss/xmss.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,21 +265,17 @@ class BOTAN_PUBLIC_API(2, 0) XMSS_PrivateKey final : public virtual XMSS_PublicK
* @param start_idx The start index.
* @param target_node_height Height of the target node.
* @param adrs Address of the tree containing the target node.
* @param hash The hash function to use
*
* @return The root node of a tree of height target_node height with the
* leftmost leaf being the hash of the WOTS+ pk with index
* start_idx.
**/
secure_vector<uint8_t> tree_hash(size_t start_idx, size_t target_node_height, XMSS_Address& adrs);
secure_vector<uint8_t> tree_hash(size_t start_idx,
size_t target_node_height,
XMSS_Address& adrs,
XMSS_Hash& hash);

void tree_hash_subtree(secure_vector<uint8_t>& result,
size_t start_idx,
size_t target_node_height,
XMSS_Address& adrs);

/**
* Helper for multithreaded tree hashing.
*/
void tree_hash_subtree(secure_vector<uint8_t>& result,
size_t start_idx,
size_t target_node_height,
Expand Down
34 changes: 12 additions & 22 deletions src/lib/pubkey/xmss/xmss_privatekey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <botan/internal/concat_util.h>
#include <botan/internal/loadstor.h>
#include <botan/internal/xmss_common_ops.h>
#include <botan/internal/xmss_hash.h>
#include <botan/internal/xmss_index_registry.h>
#include <botan/internal/xmss_signature_operation.h>

Expand Down Expand Up @@ -63,7 +64,6 @@ class XMSS_PrivateKey_Internal {
m_xmss_params(xmss_params),
m_wots_params(wots_params),
m_wots_derivation_method(wots_derivation_method),
m_hash(xmss_params),
m_prf(rng.random_vec(xmss_params.element_size())),
m_private_seed(rng.random_vec(xmss_params.element_size())),
m_index_reg(XMSS_Index_Registry::get_instance()) {}
Expand All @@ -76,18 +76,14 @@ class XMSS_PrivateKey_Internal {
m_xmss_params(xmss_params),
m_wots_params(wots_params),
m_wots_derivation_method(wots_derivation_method),
m_hash(m_xmss_params),
m_prf(std::move(prf)),
m_private_seed(std::move(private_seed)),
m_index_reg(XMSS_Index_Registry::get_instance()) {}

XMSS_PrivateKey_Internal(const XMSS_Parameters& xmss_params,
const XMSS_WOTS_Parameters& wots_params,
std::span<const uint8_t> key_bits) :
m_xmss_params(xmss_params),
m_wots_params(wots_params),
m_hash(m_xmss_params),
m_index_reg(XMSS_Index_Registry::get_instance()) {
m_xmss_params(xmss_params), m_wots_params(wots_params), m_index_reg(XMSS_Index_Registry::get_instance()) {
Comment thread
randombit marked this conversation as resolved.
/*
The code requires sizeof(size_t) >= ceil(tree_height / 8)

Expand Down Expand Up @@ -139,8 +135,6 @@ class XMSS_PrivateKey_Internal {
raw_public_key, unused_index, m_prf, m_private_seed, wots_derivation_method);
}

XMSS_Hash& hash() { return m_hash; }

const secure_vector<uint8_t>& prf_value() const { return m_prf; }

const secure_vector<uint8_t>& private_seed() { return m_private_seed; }
Expand Down Expand Up @@ -194,7 +188,6 @@ class XMSS_PrivateKey_Internal {
XMSS_WOTS_Parameters m_wots_params;
WOTS_Derivation_Method m_wots_derivation_method;

XMSS_Hash m_hash;
secure_vector<uint8_t> m_prf;
secure_vector<uint8_t> m_private_seed;
XMSS_Index_Registry& m_index_reg;
Expand All @@ -210,7 +203,8 @@ XMSS_PrivateKey::XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
XMSS_PublicKey(xmss_algo_id, rng),
m_private(std::make_shared<XMSS_PrivateKey_Internal>(m_xmss_params, m_wots_params, wots_derivation_method, rng)) {
XMSS_Address adrs;
m_root = tree_hash(0, XMSS_PublicKey::m_xmss_params.tree_height(), adrs);
XMSS_Hash hash(m_xmss_params);
m_root = tree_hash(0, XMSS_PublicKey::m_xmss_params.tree_height(), adrs, hash);
}

XMSS_PrivateKey::XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
Expand All @@ -230,7 +224,10 @@ XMSS_PrivateKey::XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
"XMSS: unexpected byte length of private seed");
}

secure_vector<uint8_t> XMSS_PrivateKey::tree_hash(size_t start_idx, size_t target_node_height, XMSS_Address& adrs) {
secure_vector<uint8_t> XMSS_PrivateKey::tree_hash(size_t start_idx,
size_t target_node_height,
XMSS_Address& adrs,
XMSS_Hash& hash) {
BOTAN_ASSERT_NOMSG(target_node_height <= 30);
BOTAN_ASSERT((start_idx % (static_cast<size_t>(1) << target_node_height)) == 0,
"Start index must be divisible by 2^{target node height}.");
Expand All @@ -245,7 +242,7 @@ secure_vector<uint8_t> XMSS_PrivateKey::tree_hash(size_t start_idx, size_t targe
// skip parallelization overhead for leaf nodes.
if(split_level == 0) {
secure_vector<uint8_t> result;
tree_hash_subtree(result, start_idx, target_node_height, adrs);
tree_hash_subtree(result, start_idx, target_node_height, adrs, hash);
return result;
}

Expand All @@ -262,7 +259,7 @@ secure_vector<uint8_t> XMSS_PrivateKey::tree_hash(size_t start_idx, size_t targe
std::vector<secure_vector<uint8_t>> nodes(subtrees,
secure_vector<uint8_t>(XMSS_PublicKey::m_xmss_params.element_size()));
std::vector<XMSS_Address> node_addresses(subtrees, adrs);
std::vector<XMSS_Hash> xmss_hash(subtrees, m_private->hash());
std::vector<XMSS_Hash> xmss_hash(subtrees, hash);
std::vector<std::future<void>> work;

// Calculate multiple subtrees in parallel.
Expand Down Expand Up @@ -317,22 +314,15 @@ secure_vector<uint8_t> XMSS_PrivateKey::tree_hash(size_t start_idx, size_t targe
node_addresses[0].set_tree_height(static_cast<uint32_t>(target_node_height - 1));
node_addresses[0].set_tree_index((node_addresses[1].get_tree_index() - 1) >> 1);
XMSS_Common_Ops::randomize_tree_hash(
nodes[0], nodes[0], nodes[1], node_addresses[0], this->public_seed(), m_private->hash(), m_xmss_params);
nodes[0], nodes[0], nodes[1], node_addresses[0], this->public_seed(), hash, m_xmss_params);
return nodes[0];
#else
secure_vector<uint8_t> result;
tree_hash_subtree(result, start_idx, target_node_height, adrs, m_private->hash());
tree_hash_subtree(result, start_idx, target_node_height, adrs, hash);
return result;
#endif
}

void XMSS_PrivateKey::tree_hash_subtree(secure_vector<uint8_t>& result,
size_t start_idx,
size_t target_node_height,
XMSS_Address& adrs) {
return tree_hash_subtree(result, start_idx, target_node_height, adrs, m_private->hash());
}

void XMSS_PrivateKey::tree_hash_subtree(
secure_vector<uint8_t>& result, size_t start_idx, size_t target_node_height, XMSS_Address& adrs, XMSS_Hash& hash) {
const secure_vector<uint8_t>& seed = this->public_seed();
Expand Down
2 changes: 1 addition & 1 deletion src/lib/pubkey/xmss/xmss_signature_operation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ wots_keysig_t XMSS_Signature_Operation::build_auth_path(XMSS_PrivateKey& priv_ke

for(size_t j = 0; j < params.tree_height(); j++) {
const size_t k = (m_leaf_idx / (static_cast<size_t>(1) << j)) ^ 0x01;
auth_path[j] = priv_key.tree_hash(k * (static_cast<size_t>(1) << j), j, adrs);
auth_path[j] = priv_key.tree_hash(k * (static_cast<size_t>(1) << j), j, adrs, m_hash);
}

return auth_path;
Expand Down
5 changes: 1 addition & 4 deletions src/tests/test_concurrent_pk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,10 @@ class Concurrent_Public_Key_Operations_Test : public Test {
ConcurrentPkTestCase("Ed448", "", "Pure"),
ConcurrentPkTestCase("SLH-DSA", "SLH-DSA-SHA2-128f"),
ConcurrentPkTestCase("HSS-LMS", "SHA-256,HW(5,8)"),
ConcurrentPkTestCase("XMSS", "XMSS-SHA2_10_256"),
};

for(const auto& tc : test_cases) {
if(tc.algo_name() == "XMSS" && !Test::run_long_tests()) {
continue;
}

auto rng = Test::new_rng(tc.algo_name());

if(auto privkey = tc.try_create_key(*rng)) {
Expand Down
Loading