9#include <botan/internal/streebog.h>
11#include <botan/exceptn.h>
12#include <botan/internal/bit_ops.h>
13#include <botan/internal/bswap.h>
14#include <botan/internal/buffer_slicer.h>
15#include <botan/internal/fmt.h>
16#include <botan/internal/loadstor.h>
17#include <botan/internal/streebog_const.h>
21#if defined(BOTAN_HAS_CPUID)
22 #include <botan/internal/cpuid.h>
30consteval std::array<std::array<uint64_t, 256>, 8> streebog_Ax_table() noexcept {
31 std::array<std::array<uint64_t, 256>, 8> Ax = {};
33 for(
size_t j = 0; j != 8; ++j) {
34 for(
size_t x = 0; x != 256; ++x) {
42const constinit auto STREEBOG_Ax = streebog_Ax_table();
44inline uint64_t force_le(uint64_t x) {
45 if constexpr(std::endian::native == std::endian::little) {
47 }
else if constexpr(std::endian::native == std::endian::big) {
50 store_le(x,
reinterpret_cast<uint8_t*
>(&x));
55inline void lps(uint64_t block[8]) {
56 const uint64_t block2[8] = {block[0], block[1], block[2], block[3], block[4], block[5], block[6], block[7]};
57 const std::span<const uint8_t> r{
reinterpret_cast<const uint8_t*
>(block2), 64};
59 for(
int i = 0; i < 8; ++i) {
60 block[i] = force_le(STREEBOG_Ax[0][r[i + 0 * 8]]) ^ force_le(STREEBOG_Ax[1][r[i + 1 * 8]]) ^
61 force_le(STREEBOG_Ax[2][r[i + 2 * 8]]) ^ force_le(STREEBOG_Ax[3][r[i + 3 * 8]]) ^
62 force_le(STREEBOG_Ax[4][r[i + 4 * 8]]) ^ force_le(STREEBOG_Ax[5][r[i + 5 * 8]]) ^
63 force_le(STREEBOG_Ax[6][r[i + 6 * 8]]) ^ force_le(STREEBOG_Ax[7][r[i + 7 * 8]]);
70 return std::make_unique<Streebog>(*
this);
74 if(output_bits != 256 && output_bits != 512) {
82 return fmt(
"Streebog-{}", m_output_bits);
86#if defined(BOTAN_HAS_STREEBOG_AVX512_GFNI)
103 const uint64_t fill = (m_output_bits == 512) ? 0 : 0x0101010101010101;
104 std::fill(m_h.begin(), m_h.end(), fill);
114 if(
const auto one_block = m_buffer.handle_unaligned_data(in)) {
119 if(m_buffer.in_alignment()) {
120 while(
const auto aligned_block = m_buffer.next_aligned_block_to_process(in)) {
132 const auto pos = m_buffer.elements_in_buffer();
134 const uint8_t padding = 0x01;
135 m_buffer.append({&padding, 1});
136 m_buffer.fill_up_with_zeros();
138 compress(m_buffer.consume().data());
141 m_buffer.fill_up_with_zeros();
142 store_le(m_count, m_buffer.directly_modify_first(
sizeof(m_count)).data());
143 compress(m_buffer.consume().data(),
true);
149 typecast_copy(output, std::span<const uint64_t>(&m_h[offset], count));
161void increment_s(
bool last_block,
const uint64_t M[8], uint64_t S[8]) {
164 for(
int i = 0; i < 8; i++) {
165 const uint64_t m = force_le(M[i]);
166 const uint64_t hi = force_le(S[i]);
167 const uint64_t t = hi + m +
carry;
171 carry = (t < m) ? 1 : 0;
180 const uint64_t N = last_block ? 0 : force_le(m_count);
182#if defined(BOTAN_HAS_STREEBOG_AVX512_GFNI)
184 compress_64_avx512_gfni(m_h.data(), M, N);
185 increment_s(last_block, M, m_S.data());
199 for(
size_t i = 0; i != 8; ++i) {
203 for(
size_t i = 0; i < 12; ++i) {
204 for(
size_t j = 0; j != 8; ++j) {
210 for(
size_t j = 0; j != 8; ++j) {
215 for(
size_t i = 0; i != 8; ++i) {
216 m_h[i] ^= hN[i] ^ M[i];
219 increment_s(last_block, M, m_S.data());
static std::optional< std::string > check(CPUID::Feature feat)
static bool has(CPUID::Feature feat)
void compress(const uint8_t input[], bool lastblock=false)
void add_data(std::span< const uint8_t > input) override
std::string provider() const override
size_t output_length() const override
void compress_64(const uint64_t input[], bool lastblock=false)
std::unique_ptr< HashFunction > copy_state() const override
void final_result(std::span< uint8_t > out) override
Streebog(size_t output_bits)
std::string name() const override
void zeroise(std::vector< T, Alloc > &vec)
const constexpr uint8_t STREEBOG_S[256]
std::string fmt(std::string_view format, const T &... args)
constexpr void typecast_copy(ToR &&out, const FromR &in)
constexpr void copy_mem(T *out, const T *in, size_t n)
constexpr auto store_le(ParamTs &&... params)
constexpr T reverse_bytes(T x)
constexpr T poly_mul(T x, uint8_t y)
void carry(int64_t &h0, int64_t &h1)
constexpr uint64_t STREEBOG_C[12][8]
constexpr uint64_t STREEBOG_L[8]