std::byte support
Hi,
from my perspective, the way to go for the future is to support std::byte as a native byte type. But Botan actually makes it hard to use std::byte. One of the most critical parts is actually this requirement of secure_alloacator:
template <typename T>
#if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0
/*
* Assert exists to prevent someone from doing something that will
* probably crash anyway (like secure_vector<non_POD_t> where ~non_POD_t
* deletes a member pointer which was zeroed before it ran).
* MSVC in debug mode uses non-integral proxy types in container types
* like std::vector, thus we disable the check there.
*/
requires std::is_integral<T>::value
#endif
It is still Botan 2 because Botan 3 still does not have a conan recipe. But I would at least allow the std::byte type here. In the long run, it will be very beneficial as well, that the implementer can use the API with std::byte as well.
Best regards, Trafo
[EDIT] But in general awesome work. If there were std::byte support in general, it would be super easy and modern to use crypto lib, which gives many possibilities. Could we just replace std::uint8_t with a botan_byte? Where implementers can define if they want std::byte or for legacy reasons std::uint8_t?
I agree that we should give std::byte more attention in the public API.
To begin with, there's certainly no reason for Botan::secure_vector<> to prohibit using std::byte. Though, on the other hand, I don't see much use to it either. At least until the library's public API allows consuming secure_vector<std::byte>. Or am I missing something?
That said, adding public overloads that consume and produce data as containers of std::byte shouldn't be hard to do -- given that it is designed to co-exist with integer-type API (read: uint8_t). Perhaps this can even go hand-in-hand with the ongoing switch to std::span<uint8_t>-based public (and private) APIs. Even without direct support of std::byte, this new interface paradigm might be beneficial to you with a bit of glue:
template <std::ranges::contiguous_range R>
std::span<const uint8_t> as_botan_span(R&& range)
requires(sizeof(std::ranges::range_value_t<R>) == 1)
{
return {reinterpret_cast<const uint8_t*>(std::ranges::data(range)), std::ranges::size(range)};
}
I don't think that Botan will internally switch away from uint8_t anytime soon, though.
It is still Botan 2 because Botan 3 still does not have a conan recipe.
Mea culpa. 😞 We're working on that.
Yes, I can understand it. Mainly I want to raise awareness because std::byte will be the thing for bytes in the future in the C++ world. And it is better to consider it earlier than later. For example, in C++ it is straightforward to convert everything into bytes (std::as_bytes). I assume in the future even more features will be introduced. It is also the stronger type for transferring data compared to uint8_t which is in the end an integral as well and used for those purposes as well. I agree that Botan::secure_vector should not support std::byte till it is supported by the API. I could just create my own version of it in my project. Using your conversion methods is helping in most of the cases, but sadly sometimes the API of Botan is only working directly with Botan::secure_vector<uint8_t>. For example, Botan::AEAD_Mode::finalize(), offers only a version, where the Botan::secure_vector<uint8_t> needs to be used for the final block. This function is appending or removing the tag to this vector. In those cases, my only choice to handle this case is to copy the last block around.
But again, super nice library. I feel liberated after switching from libsodium to this library.