/* * XMSS Address * (C) 2016 Matthias Gierlings * * Botan is released under the Simplified BSD License (see license.txt) **/ #ifndef BOTAN_XMSS_TOOLS_H_ #define BOTAN_XMSS_TOOLS_H_ #include #include #include #include namespace Botan { /** * Helper tools for low level byte operations required * for the XMSS implementation. **/ class XMSS_Tools { public: XMSS_Tools(const XMSS_Tools&) = delete; void operator=(const XMSS_Tools&) = delete; /** * Concatenates the byte representation in big-endian order of any * integral value to a secure_vector. * * @param target Vector to concatenate the byte representation of the * integral value to. * @param src integral value to concatenate. **/ template::value, void>::type> static void concat(secure_vector& target, const T& src); /** * Concatenates the last n bytes of the byte representation in big-endian * order of any integral value to a to a secure_vector. * * @param target Vector to concatenate the byte representation of the * integral value to. * @param src Integral value to concatenate. * @param len number of bytes to concatenate. This value must be smaller * or equal to the size of type T. **/ template ::value, void>::type> static void concat(secure_vector& target, const T& src, size_t len); private: XMSS_Tools(); }; template void XMSS_Tools::concat(secure_vector& target, const T& src) { const uint8_t* src_bytes = reinterpret_cast(&src); if(CPUID::is_little_endian()) { std::reverse_copy(src_bytes, src_bytes + sizeof(src), std::back_inserter(target)); } else { std::copy(src_bytes, src_bytes + sizeof(src), std::back_inserter(target)); } } template void XMSS_Tools::concat(secure_vector& target, const T& src, size_t len) { size_t c = static_cast(std::min(len, sizeof(src))); if(len > sizeof(src)) { target.resize(target.size() + len - sizeof(src), 0); } const uint8_t* src_bytes = reinterpret_cast(&src); if(CPUID::is_little_endian()) { std::reverse_copy(src_bytes, src_bytes + c, std::back_inserter(target)); } else { std::copy(src_bytes + sizeof(src) - c, src_bytes + sizeof(src), std::back_inserter(target)); } } } #endif