Skip to content

Commit

Permalink
fix some compiler warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
FAlbertDev committed Sep 28, 2023
1 parent 3894932 commit e8954a1
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 52 deletions.
13 changes: 8 additions & 5 deletions src/lib/pubkey/hss_lms/hss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <botan/internal/hss.h>
#include <botan/internal/hss_lms_utils.h>
#include <botan/internal/loadstor.h>
#include <botan/internal/safeint.h>
#include <botan/internal/scan_name.h>
#include <botan/internal/stl_util.h>

Expand Down Expand Up @@ -62,7 +63,7 @@ std::vector<LMS_Tree_Node_Idx> derive_lms_leaf_indices_from_hss_index(HSS_Sig_Id
const HSS_LMS_Params::LMS_LMOTS_Params_Pair& layer_params = hss_params.params_at_level(layer);
size_t layer_h = layer_params.lms_params().h();
q.at(layer.get()) =
LMS_Tree_Node_Idx(static_cast<uint32_t>(hss_idx.get() % static_cast<uint64_t>(1ULL << layer_h)));
LMS_Tree_Node_Idx(checked_cast_to<uint32_t>(hss_idx.get() % checked_cast_to<uint64_t>(1ULL << layer_h)));
hss_idx = hss_idx >> layer_h;
}
BOTAN_ARG_CHECK(hss_idx == HSS_Sig_Idx(0), "HSS Tree is exhausted");
Expand All @@ -89,8 +90,10 @@ HSS_LMS_Params::HSS_LMS_Params(std::string_view algo_params) {
SCAN_Name scan_layer(scan.arg(i));
BOTAN_ARG_CHECK(scan_layer.algo_name() == "HW", "Invalid name for layer parameters");
BOTAN_ARG_CHECK(scan_layer.arg_count() == 2, "Invalid number of layer parameters");
const auto h = scan_layer.arg_as_integer(0);
const auto w = scan_layer.arg_as_integer(1);
const auto h =
checked_cast_to_or_throw<uint8_t, Invalid_Argument>(scan_layer.arg_as_integer(0), "Invalid parameter");
const auto w =
checked_cast_to_or_throw<uint8_t, Invalid_Argument>(scan_layer.arg_as_integer(1), "Invalid parameter");
m_lms_lmots_params.push_back({LMS_Params::create_or_throw(hash, h), LMOTS_Params::create_or_throw(hash, w)});
}
m_max_sig_count = calc_max_sig_count();
Expand Down Expand Up @@ -354,7 +357,7 @@ size_t HSS_LMS_PublicKeyInternal::size() const {
}

bool HSS_LMS_PublicKeyInternal::verify_signature(std::span<const uint8_t> msg, const HSS_Signature& sig) const {
if(static_cast<HSS_Level>(sig.Nspk()) + 1 != L()) {
if(HSS_Level(checked_cast_to<uint32_t>(sig.Nspk())) + 1 != L()) {
// HSS levels in the public key does not match with the signature's
return false;
}
Expand Down Expand Up @@ -400,7 +403,7 @@ HSS_Signature HSS_Signature::from_bytes_or_throw(std::span<const uint8_t> sig_by
if(!slicer.empty()) {
throw Decoding_Error("HSS-LMS signature contains more bytes than expected.");
}
return HSS_Signature(static_cast<uint8_t>(Nspk), std::move(signed_pub_keys), std::move(sig));
return HSS_Signature(checked_cast_to<uint8_t>(Nspk), std::move(signed_pub_keys), std::move(sig));
}

size_t HSS_Signature::size(const HSS_LMS_Params& params) {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/pubkey/hss_lms/hss.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <botan/asn1_obj.h>
#include <botan/internal/lm_ots.h>
#include <botan/internal/lms.h>
#include <botan/internal/safeint.h>

#include <cstdint>
#include <memory>
Expand Down Expand Up @@ -99,7 +100,7 @@ class BOTAN_TEST_API HSS_LMS_Params final {
/**
* @brief Returns the number of layers the HSS tree has.
*/
HSS_Level L() const { return HSS_Level(static_cast<uint32_t>(m_lms_lmots_params.size())); }
HSS_Level L() const { return HSS_Level(checked_cast_to<uint32_t>(m_lms_lmots_params.size())); }

/**
* @brief The maximal number of signatures allowed for these HSS parameters
Expand Down
18 changes: 9 additions & 9 deletions src/lib/pubkey/hss_lms/lm_ots.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,29 @@ std::vector<uint8_t> gen_Q_with_cksm(const LMOTS_Params& params,
} // namespace

LMOTS_Params LMOTS_Params::create_or_throw(LMOTS_Algorithm_Type type) {
uint8_t type_value = static_cast<uint8_t>(type);
uint8_t type_value = checked_cast_to_or_throw<uint8_t, Decoding_Error>(type, "Unsupported LM-OTS algorithm type");

if(type >= LMOTS_Algorithm_Type::SHA256_N32_W1 && type <= LMOTS_Algorithm_Type::SHA256_N32_W8) {
uint8_t w = 1 << (type_value - static_cast<uint8_t>(LMOTS_Algorithm_Type::SHA256_N32_W1));
uint8_t w = 1 << (type_value - checked_cast_to<uint8_t>(LMOTS_Algorithm_Type::SHA256_N32_W1));
return LMOTS_Params(type, "SHA-256", w);
}
if(type >= LMOTS_Algorithm_Type::SHA256_N24_W1 && type <= LMOTS_Algorithm_Type::SHA256_N24_W8) {
uint8_t w = 1 << (type_value - static_cast<uint8_t>(LMOTS_Algorithm_Type::SHA256_N24_W1));
uint8_t w = 1 << (type_value - checked_cast_to<uint8_t>(LMOTS_Algorithm_Type::SHA256_N24_W1));
return LMOTS_Params(type, "Truncated(SHA-256,192)", w);
}
if(type >= LMOTS_Algorithm_Type::SHAKE_N32_W1 && type <= LMOTS_Algorithm_Type::SHAKE_N32_W8) {
uint8_t w = 1 << (type_value - static_cast<uint8_t>(LMOTS_Algorithm_Type::SHAKE_N32_W1));
uint8_t w = 1 << (type_value - checked_cast_to<uint8_t>(LMOTS_Algorithm_Type::SHAKE_N32_W1));
return LMOTS_Params(type, "SHAKE-256(256)", w);
}
if(type >= LMOTS_Algorithm_Type::SHAKE_N24_W1 && type <= LMOTS_Algorithm_Type::SHAKE_N24_W8) {
uint8_t w = 1 << (type_value - static_cast<uint8_t>(LMOTS_Algorithm_Type::SHAKE_N24_W1));
uint8_t w = 1 << (type_value - checked_cast_to<uint8_t>(LMOTS_Algorithm_Type::SHAKE_N24_W1));
return LMOTS_Params(type, "SHAKE-256(192)", w);
}

throw Decoding_Error("Unsupported LM-OTS algorithm type");
}

LMOTS_Params LMOTS_Params::create_or_throw(std::string_view hash_name, size_t w) {
LMOTS_Params LMOTS_Params::create_or_throw(std::string_view hash_name, uint8_t w) {
BOTAN_ARG_CHECK(w == 1 || w == 2 || w == 4 || w == 8, "Invalid w value");
auto type_offset = high_bit(w) - 1;
LMOTS_Algorithm_Type base_type;
Expand All @@ -148,7 +148,7 @@ LMOTS_Params LMOTS_Params::create_or_throw(std::string_view hash_name, size_t w)
} else {
throw Decoding_Error("Unsupported hash function");
}
auto type = static_cast<LMOTS_Algorithm_Type>(static_cast<uint8_t>(base_type) + type_offset);
auto type = checked_cast_to<LMOTS_Algorithm_Type>(checked_cast_to<uint8_t>(base_type) + type_offset);
return LMOTS_Params(type, hash_name, w);
}

Expand All @@ -159,8 +159,8 @@ LMOTS_Params::LMOTS_Params(LMOTS_Algorithm_Type algorithm_type, std::string_view
// RFC 8553 Appendix B - Parameter Computation
auto u = ceil_division<size_t>(8 * m_n, m_w); // ceil(8*n/w)
auto v = ceil_division<size_t>(high_bit(((1 << m_w) - 1) * u), m_w); // ceil((floor(lg[(2^w - 1) * u]) + 1) / w)
m_ls = 16 - (v * w);
m_p = u + v;
m_ls = checked_cast_to<uint8_t>(16 - (v * w));
m_p = checked_cast_to<uint16_t>(u + v);
}

LMOTS_Signature::LMOTS_Signature(LMOTS_Algorithm_Type lmots_type,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/pubkey/hss_lms/lm_ots.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class BOTAN_TEST_API LMOTS_Params {
* @param w the width (in bits) of the Winternitz coefficients.
* @throws Decoding_Error If the algorithm type is unknown
*/
static LMOTS_Params create_or_throw(std::string_view hash_name, size_t w);
static LMOTS_Params create_or_throw(std::string_view hash_name, uint8_t w);

/**
* @brief Returns the LM-OTS algorithm type.
Expand Down
15 changes: 8 additions & 7 deletions src/lib/pubkey/hss_lms/lms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <botan/internal/lms.h>

#include <botan/internal/hss_lms_utils.h>
#include <botan/internal/safeint.h>

namespace Botan {
namespace {
Expand Down Expand Up @@ -119,29 +120,29 @@ void lms_treehash(StrongSpan<LMS_Tree_Node> out_root,
} // namespace

LMS_Params LMS_Params::create_or_throw(LMS_Algorithm_Type type) {
uint8_t type_value = static_cast<uint8_t>(type);
uint8_t type_value = checked_cast_to_or_throw<uint8_t, Decoding_Error>(type, "Unsupported LMS algorithm type");

if(type >= LMS_Algorithm_Type::SHA256_M32_H5 && type <= LMS_Algorithm_Type::SHA256_M32_H25) {
uint8_t h = 5 * (type_value - static_cast<uint8_t>(LMS_Algorithm_Type::SHA256_M32_H5) + 1);
uint8_t h = 5 * (type_value - checked_cast_to<uint8_t>(LMS_Algorithm_Type::SHA256_M32_H5) + 1);
return LMS_Params(type, "SHA-256", h);
}
if(type >= LMS_Algorithm_Type::SHA256_M24_H5 && type <= LMS_Algorithm_Type::SHA256_M24_H25) {
uint8_t h = 5 * (type_value - static_cast<uint8_t>(LMS_Algorithm_Type::SHA256_M24_H5) + 1);
uint8_t h = 5 * (type_value - checked_cast_to<uint8_t>(LMS_Algorithm_Type::SHA256_M24_H5) + 1);
return LMS_Params(type, "Truncated(SHA-256,192)", h);
}
if(type >= LMS_Algorithm_Type::SHAKE_M32_H5 && type <= LMS_Algorithm_Type::SHAKE_M32_H25) {
uint8_t h = 5 * (type_value - static_cast<uint8_t>(LMS_Algorithm_Type::SHAKE_M32_H5) + 1);
uint8_t h = 5 * (type_value - checked_cast_to<uint8_t>(LMS_Algorithm_Type::SHAKE_M32_H5) + 1);
return LMS_Params(type, "SHAKE-256(256)", h);
}
if(type >= LMS_Algorithm_Type::SHAKE_M24_H5 && type <= LMS_Algorithm_Type::SHAKE_M24_H25) {
uint8_t h = 5 * (type_value - static_cast<uint8_t>(LMS_Algorithm_Type::SHAKE_M24_H5) + 1);
uint8_t h = 5 * (type_value - checked_cast_to<uint8_t>(LMS_Algorithm_Type::SHAKE_M24_H5) + 1);
return LMS_Params(type, "SHAKE-256(192)", h);
}

throw Decoding_Error("Unsupported LMS algorithm type");
}

LMS_Params LMS_Params::create_or_throw(std::string_view hash_name, size_t h) {
LMS_Params LMS_Params::create_or_throw(std::string_view hash_name, uint8_t h) {
BOTAN_ARG_CHECK(h == 5 || h == 10 || h == 15 || h == 20 || h == 25, "Invalid h value");
auto type_offset = h / 5 - 1;
LMS_Algorithm_Type base_type;
Expand All @@ -157,7 +158,7 @@ LMS_Params LMS_Params::create_or_throw(std::string_view hash_name, size_t h) {
} else {
throw Decoding_Error("Unsupported hash function");
}
auto type = static_cast<LMS_Algorithm_Type>(static_cast<uint8_t>(base_type) + type_offset);
auto type = checked_cast_to<LMS_Algorithm_Type>(checked_cast_to<uint8_t>(base_type) + type_offset);
return LMS_Params(type, hash_name, h);
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/pubkey/hss_lms/lms.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class BOTAN_TEST_API LMS_Params {
* @param h The height of the tree.
* @throws Decoding_Error If the algorithm type is unknown
*/
static LMS_Params create_or_throw(std::string_view hash_name, size_t h);
static LMS_Params create_or_throw(std::string_view hash_name, uint8_t h);

/**
* @brief Retuns the LMS algorithm type.
Expand Down
20 changes: 15 additions & 5 deletions src/lib/utils/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ struct is_strong_type<Strong<Ts...>> : std::true_type {};
template <typename... Ts>
constexpr bool is_strong_type_v = is_strong_type<std::remove_const_t<Ts>...>::value;

/**
* Checks whether a strong type has the @p Capability included in its @p Tags type pack.
*/
template <typename Capability, typename T, typename... Tags>
constexpr auto strong_type_has_capability(Strong<T, Tags...>) {
if constexpr((std::is_same_v<Capability, Tags> || ...)) {
return std::true_type();
} else {
return std::false_type();
}
}

namespace concepts {

// TODO: C++20 use std::convertible_to<> that was not available in Android NDK
Expand Down Expand Up @@ -118,11 +130,9 @@ template <class T>
concept contiguous_strong_type = strong_type<T> && contiguous_container<T>;

template <typename T, typename Capability>
concept is_strong_type_with_capability = requires(T a) {
{
strong_type_has_capability<Capability>(a)
} -> std::same_as<std::true_type>;
};
concept strong_type_with_capability = requires(T a) {
{ strong_type_has_capability<Capability>(a) } -> std::same_as<std::true_type>;
};

// std::integral is a concept that is shipped with C++20 but Android NDK is not
// yet there.
Expand Down
11 changes: 8 additions & 3 deletions src/lib/utils/safeint.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,20 @@ inline std::optional<size_t> checked_mul(size_t x, size_t y) {
return z;
}

template <typename RT, typename AT>
RT checked_cast_to(AT i) {
template <typename RT, typename ExceptionType, typename AT>
constexpr RT checked_cast_to_or_throw(AT i, std::string_view error_msg_on_fail) {
RT c = static_cast<RT>(i);
if(i != static_cast<AT>(c)) {
throw Internal_Error("Error during integer conversion");
throw ExceptionType(error_msg_on_fail);
}
return c;
}

template <typename RT, typename AT>
constexpr RT checked_cast_to(AT i) {
return checked_cast_to_or_throw<RT, Internal_Error>(i, "Error during integer conversion");
}

#define BOTAN_CHECKED_ADD(x, y) checked_add(x, y, __FILE__, __LINE__)
#define BOTAN_CHECKED_MUL(x, y) checked_mul(x, y)

Expand Down
12 changes: 0 additions & 12 deletions src/lib/utils/strong_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,6 @@ class Strong_Adapter<T> : public Strong_Base<T> {

} // namespace detail

/**
* Checks whether a strong type has the @p Capability included in its @p Tags type pack.
*/
template <typename Capability, typename T, typename... Tags>
constexpr auto strong_type_has_capability(Strong<T, Tags...>) {
if constexpr(Botan::detail::has_capability<Capability, Tags...>) {
return std::true_type{};
} else {
return std::false_type{};
}
}

/**
* Strong types can be used as wrappers around common types to provide
* compile time semantics. They usually contribute to more maintainable and
Expand Down
4 changes: 2 additions & 2 deletions src/lib/utils/tree_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ concept tree_node = contiguous_container<T>;
* The left most node of a layer has the index 0.
*/
template <typename T>
concept tree_node_index = is_strong_type_with_capability<T, EnableArithmeticWithPlainNumber>;
concept tree_node_index = strong_type_with_capability<T, EnableArithmeticWithPlainNumber>;

/**
* @brief A layer in a Tree.
*
* The bottom layer is the layer 0.
*/
template <typename T>
concept tree_layer_index = is_strong_type_with_capability<T, EnableArithmeticWithPlainNumber>;
concept tree_layer_index = strong_type_with_capability<T, EnableArithmeticWithPlainNumber>;

template <strong_type S>
struct strong_span_type {};
Expand Down
18 changes: 12 additions & 6 deletions src/tests/test_hss_lms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,15 @@ class HSS_LMS_Too_Short_Test final : public Test {
auto sk = Botan::create_private_key("HSS-LMS", Test::rng(), "Truncated(SHA-256,192),HW(5,8)");

auto sk_bytes = sk->private_key_bits();
result.test_no_throw("Entire private key valid",
[&]() { std::make_unique<Botan::HSS_LMS_PrivateKey>(sk_bytes); });
result.test_no_throw("Entire private key valid", [&]() {
Botan::HSS_LMS_PrivateKey key(sk_bytes);
BOTAN_UNUSED(key);
});
for(size_t n = 0; n < sk_bytes.size(); ++n) {
result.test_throws<Botan::Decoding_Error>("Partial private key invalid", [&]() {
std::span<const uint8_t> partial_key = {sk_bytes.data(), n};
std::make_unique<Botan::HSS_LMS_PrivateKey>(partial_key);
Botan::HSS_LMS_PrivateKey key(partial_key);
BOTAN_UNUSED(key);
});
}
return result;
Expand All @@ -158,12 +161,15 @@ class HSS_LMS_Too_Short_Test final : public Test {
auto sk = Botan::create_private_key("HSS-LMS", Test::rng(), "Truncated(SHA-256,192),HW(5,8)");

auto sk_bytes = sk->public_key_bits();
result.test_no_throw("Entire public key valid",
[&]() { std::make_unique<Botan::HSS_LMS_PublicKey>(sk_bytes); });
result.test_no_throw("Entire public key valid", [&]() {
Botan::HSS_LMS_PublicKey key(sk_bytes);
BOTAN_UNUSED(key);
});
for(size_t n = 0; n < sk_bytes.size(); ++n) {
result.test_throws<Botan::Decoding_Error>("Partial public key invalid", [&]() {
std::span<const uint8_t> partial_key = {sk_bytes.data(), n};
std::make_unique<Botan::HSS_LMS_PublicKey>(partial_key);
Botan::HSS_LMS_PublicKey key(partial_key);
BOTAN_UNUSED(key);
});
}
return result;
Expand Down

0 comments on commit e8954a1

Please sign in to comment.